|
85317
|
2920
|
37
|
2026-05-28T12:17:56.858386+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970676858_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeRefactorRunToolsGi PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"84‹$0(ah]A100% <78• Thu 28 May 15:17:56181ec2-user@ip-10-30-140-...₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
-2845353526474952539
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeRefactorRunToolsGi PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"84‹$0(ah]A100% <78• Thu 28 May 15:17:56181ec2-user@ip-10-30-140-...₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85315
|
NULL
|
NULL
|
NULL
|
|
85316
|
2921
|
38
|
2026-05-28T12:17:56.757485+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970676757_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
rapstomViewCoocWindowFV faVsco.|s ~#12121 on JY-20 rapstomViewCoocWindowFV faVsco.|s ~#12121 on JY-20963-fx-lProinet vwnapers.oh©ActivityControlier.php© VoiceConsentPrefix.phpen NoticationsnObservers© AccountObserver.phpCVActvwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.pho© ProfileObserver.phg© SocialAccountObserver.php© UserObserver.pho© UserRoleObserver.phc> (l Policiesa ProvidersCn Queueu ReoositonieCn RulesvserviceDa ActivityAireoorsAvaratlealendarleonterenegRtllneonimconnenimermobiacteTm Nacorate A chivinDummym HelnarsHubspol(i) AccountSyncStrategyMAetioneD ContactSyncStrateay› DDTO› Fieldswn taueeaOLeAkоkyscrco.onc Kemelons(©) Hubspot.JournalPollinaService.ohp xpap auloloone$512cass nuosco ourhalroto noserv331333(C) HubspotClientCredenti@ HubspotDealWebhooks 340(C) Hubspot.JournalApiClie© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho© JournalBatchSizellmitEC) Journa Eventtranstorm0 Metadata@poortunityswncstrateo→lmlpae natiooprosnad SaarchChrateoU Sarnce tiraite* Acquire exclusive polling lock to prevent aultiple instances1 usageonivare functsion acausrerotsinalockio: boolSexpiresAt = now®->addSeconds(self::LOCK-T/L_SECONDS)->tolSOStringO/l Use atonic operation to set both lock and expiration dataStockData ="Locked' => true'expires at' => SexpiresAt,'acquired at' => now(->toIS0String• Extract Surround // = : }) for atonic lock acquisitionSlockAcquired = Redis::set( key: self::POLLING_LOCK,KEY, json_encode(SlockData), options: 'EX*, self:3$717Sif (SlockAcquired) "MmsoslasLorkkenewal 8eteohLog::info( message: "[HubSpot Journal Polling) Acquired polling lock', (exoNesgsexoesD):netuon tboobl Slockacausinede*Releese the nobane lock*/2 usaaesoniivate functiion releasePorsinglackot wondte73273s* Force release the polling lock (for emergency situations)3 usaoespublic function forceReleaseLock(): voidf...}gaaa* Signal the polling service to stoo gracefullepublic function requeststop): void...,tian vou can safely uninstall Hunsnell without affectina the Catonadas foe othar lanquaoas. 114 minutes aooTextRelayServiceTestA SF fiminny@localhost)•• Thu 28 May 15:17:56+0.console (PROD) x C Service.phpds consoeleu.Dojminnyv045 A1 A41 У 66 ACONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (ouner)' ELSE "* END) AS user_1dWHERE uuid to_bin( [CREDIT_CARD]-927f-4f4da2a8185c') = uuid: # 80186192 N0Cacaado CodoxoKick off a new proinet. Make chanod.SEIFM+ EROM eo Geld data&•I0TM actvs tes a 0M &dlactvsty sdea.aWHERE activity_id = 79933459'hs_activity_type";select * fron text_relays where created_at > ^2826-05-01':select * fron activities where user id IN (7168, 18688) and created at > '2026-05-22' order by id descselect * fron users where tean_id = 1 and id IN (18688, 13934, 7169):select * fron activities where user id = 7168 order by id desc Linit 10-select x fron teansselect * fron activity searches where user_1d = 31054:activity seanch_ filters where activity_search_id TN (88882. 88992)c. Fix Texikelay service TesteC Multi-Picklist Layout Displa")Hode swioth56myWedelsteeoeltttlchareWhiroh*4 space...
|
NULL
|
-7972193424313891883
|
NULL
|
click
|
ocr
|
NULL
|
rapstomViewCoocWindowFV faVsco.|s ~#12121 on JY-20 rapstomViewCoocWindowFV faVsco.|s ~#12121 on JY-20963-fx-lProinet vwnapers.oh©ActivityControlier.php© VoiceConsentPrefix.phpen NoticationsnObservers© AccountObserver.phpCVActvwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.pho© ProfileObserver.phg© SocialAccountObserver.php© UserObserver.pho© UserRoleObserver.phc> (l Policiesa ProvidersCn Queueu ReoositonieCn RulesvserviceDa ActivityAireoorsAvaratlealendarleonterenegRtllneonimconnenimermobiacteTm Nacorate A chivinDummym HelnarsHubspol(i) AccountSyncStrategyMAetioneD ContactSyncStrateay› DDTO› Fieldswn taueeaOLeAkоkyscrco.onc Kemelons(©) Hubspot.JournalPollinaService.ohp xpap auloloone$512cass nuosco ourhalroto noserv331333(C) HubspotClientCredenti@ HubspotDealWebhooks 340(C) Hubspot.JournalApiClie© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho© JournalBatchSizellmitEC) Journa Eventtranstorm0 Metadata@poortunityswncstrateo→lmlpae natiooprosnad SaarchChrateoU Sarnce tiraite* Acquire exclusive polling lock to prevent aultiple instances1 usageonivare functsion acausrerotsinalockio: boolSexpiresAt = now®->addSeconds(self::LOCK-T/L_SECONDS)->tolSOStringO/l Use atonic operation to set both lock and expiration dataStockData ="Locked' => true'expires at' => SexpiresAt,'acquired at' => now(->toIS0String• Extract Surround // = : }) for atonic lock acquisitionSlockAcquired = Redis::set( key: self::POLLING_LOCK,KEY, json_encode(SlockData), options: 'EX*, self:3$717Sif (SlockAcquired) "MmsoslasLorkkenewal 8eteohLog::info( message: "[HubSpot Journal Polling) Acquired polling lock', (exoNesgsexoesD):netuon tboobl Slockacausinede*Releese the nobane lock*/2 usaaesoniivate functiion releasePorsinglackot wondte73273s* Force release the polling lock (for emergency situations)3 usaoespublic function forceReleaseLock(): voidf...}gaaa* Signal the polling service to stoo gracefullepublic function requeststop): void...,tian vou can safely uninstall Hunsnell without affectina the Catonadas foe othar lanquaoas. 114 minutes aooTextRelayServiceTestA SF fiminny@localhost)•• Thu 28 May 15:17:56+0.console (PROD) x C Service.phpds consoeleu.Dojminnyv045 A1 A41 У 66 ACONCAT(u.id, CASE WHEN U.id = t.ouner_id THEN • (ouner)' ELSE "* END) AS user_1dWHERE uuid to_bin( [CREDIT_CARD]-927f-4f4da2a8185c') = uuid: # 80186192 N0Cacaado CodoxoKick off a new proinet. Make chanod.SEIFM+ EROM eo Geld data&•I0TM actvs tes a 0M &dlactvsty sdea.aWHERE activity_id = 79933459'hs_activity_type";select * fron text_relays where created_at > ^2826-05-01':select * fron activities where user id IN (7168, 18688) and created at > '2026-05-22' order by id descselect * fron users where tean_id = 1 and id IN (18688, 13934, 7169):select * fron activities where user id = 7168 order by id desc Linit 10-select x fron teansselect * fron activity searches where user_1d = 31054:activity seanch_ filters where activity_search_id TN (88882. 88992)c. Fix Texikelay service TesteC Multi-Picklist Layout Displa")Hode swioth56myWedelsteeoeltttlchareWhiroh*4 space...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85315
|
2920
|
36
|
2026-05-28T12:17:53.998788+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970673998_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes
Hide This Notification...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12121 on JY-20963-fix-import-on-deleted-entity, menu","depth":5,"on_screen":true,"help_text":"Pull request #12121 exists for current branch JY-20963-fix-import-on-deleted-entity","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-3867889705823262686
|
-1183062619475730196
|
typing_pause
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes
Hide This Notification...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85314
|
2921
|
37
|
2026-05-28T12:17:53.897958+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970673897_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12121 on JY-20963-fix-import-on-deleted-entity, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.11569149,"height":0.025538707},"on_screen":true,"help_text":"Pull request #12121 exists for current branch JY-20963-fix-import-on-deleted-entity","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8374335,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12","depth":4,"bounds":{"left":0.37865692,"top":0.15003991,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"bounds":{"left":0.39029256,"top":0.15003991,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39993352,"top":0.14844373,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40724733,"top":0.14844373,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41589096,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.4245346,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.43550533,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44414893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.45279256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.4637633,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47473404,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.5013298,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.51230055,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
490348651913652116
|
-30141114868883220
|
typing_pause
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes...
|
85313
|
NULL
|
NULL
|
NULL
|
|
85313
|
2921
|
36
|
2026-05-28T12:17:51.322679+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970671322_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes
Hide This Notification
Code changed:
Hide
45
1
41
66
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.own...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12121 on JY-20963-fix-import-on-deleted-entity, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.11569149,"height":0.025538707},"on_screen":true,"help_text":"Pull request #12121 exists for current branch JY-20963-fix-import-on-deleted-entity","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8374335,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12","depth":4,"bounds":{"left":0.37865692,"top":0.15003991,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"bounds":{"left":0.39029256,"top":0.15003991,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39993352,"top":0.14844373,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40724733,"top":0.14844373,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41589096,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.4245346,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.43550533,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44414893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.45279256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.4637633,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47473404,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.5013298,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.51230055,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"45","depth":4,"bounds":{"left":0.6938165,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.70611703,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"41","depth":4,"bounds":{"left":0.71542555,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"66","depth":4,"bounds":{"left":0.72706115,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7390292,"top":0.12210695,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7463431,"top":0.12210695,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01';\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');\n\n# ***************\nSELECT DISTINCT u.id, u.email, u.name, u.softphone_number, COUNT(a.id) as sms_count\nFROM users u\nINNER JOIN activities a ON u.id = .user_id\nWHERE a.type LIKE 'sms%'\nAND a.created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)\nGROUP BY u.id, u.email, u.name, u.softphone_number\nORDER BY sms_count DESC;\n\nselect * from teams where id = 1;\n\nselect * from roles;\n\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1117 and sa.provider = 'hubspot';\nSELECT * FROM activities WHERE uuid_to_bin('8024fffb-2df7-4017-91f4-d9f896050248') = uuid; # 79933459 YES\nSELECT * FROM activities WHERE uuid_to_bin('25529043-8094-4781-927f-4f4da2a8185c') = uuid; # 80186192 NO\nSELECT * FROM crm_configurations WHERE id = 1053;\nSELECT * FROM teams WHERE id = 1117;\nselect * from users where id = 30249;\nselect * from playbooks where id = 5473;\nselect * from playbook_categories where id = 43783;\nselect * from playbook_categories where playbook_id = 5473;\nselect * from crm_fields where id = 659242;\nselect * from crm_field_values where crm_field_id = 659242;\n\nSELECT * FROM crm_field_data fd\n# JOIN crm_fields f ON fd.crm_field_id = f.id\n# JOIN activities a ON fd.activity_id = a.id\nWHERE activity_id = 79933459\n# AND f.crm_provider_id = 'hs_activity_type';\n\n\nSELECT * FROM activity_messages;\nselect * from text_relays where created_at > '2026-05-01';\nselect * from activities where user_id IN (7160, 18608) and created_at > '2026-05-22' order by id desc;\nselect * from users where team_id = 1 and id IN (18608, 13934, 7160);\nselect * from activities where user_id = 7160 order by id desc limit 10;\n\nselect * from accounts where team_id = 1 and name = 'Column5';\n\nselect * from users where name like '%Subra%'; # 31054, 1117\nselect * from teams where id = 1117;\nselect * from activity_searches where user_id = 31054;\nselect * from activity_search_filters where activity_search_id IN (88882, 88902);","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01';\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');\n\n# ***************\nSELECT DISTINCT u.id, u.email, u.name, u.softphone_number, COUNT(a.id) as sms_count\nFROM users u\nINNER JOIN activities a ON u.id = .user_id\nWHERE a.type LIKE 'sms%'\nAND a.created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)\nGROUP BY u.id, u.email, u.name, u.softphone_number\nORDER BY sms_count DESC;\n\nselect * from teams where id = 1;\n\nselect * from roles;\n\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1117 and sa.provider = 'hubspot';\nSELECT * FROM activities WHERE uuid_to_bin('8024fffb-2df7-4017-91f4-d9f896050248') = uuid; # 79933459 YES\nSELECT * FROM activities WHERE uuid_to_bin('25529043-8094-4781-927f-4f4da2a8185c') = uuid; # 80186192 NO\nSELECT * FROM crm_configurations WHERE id = 1053;\nSELECT * FROM teams WHERE id = 1117;\nselect * from users where id = 30249;\nselect * from playbooks where id = 5473;\nselect * from playbook_categories where id = 43783;\nselect * from playbook_categories where playbook_id = 5473;\nselect * from crm_fields where id = 659242;\nselect * from crm_field_values where crm_field_id = 659242;\n\nSELECT * FROM crm_field_data fd\n# JOIN crm_fields f ON fd.crm_field_id = f.id\n# JOIN activities a ON fd.activity_id = a.id\nWHERE activity_id = 79933459\n# AND f.crm_provider_id = 'hs_activity_type';\n\n\nSELECT * FROM activity_messages;\nselect * from text_relays where created_at > '2026-05-01';\nselect * from activities where user_id IN (7160, 18608) and created_at > '2026-05-22' order by id desc;\nselect * from users where team_id = 1 and id IN (18608, 13934, 7160);\nselect * from activities where user_id = 7160 order by id desc limit 10;\n\nselect * from accounts where team_id = 1 and name = 'Column5';\n\nselect * from users where name like '%Subra%'; # 31054, 1117\nselect * from teams where id = 1117;\nselect * from activity_searches where user_id = 31054;\nselect * from activity_search_filters where activity_search_id IN (88882, 88902);","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"}]...
|
2526630547225287665
|
1137771414947247693
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes
Hide This Notification
Code changed:
Hide
45
1
41
66
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.own...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85312
|
2920
|
35
|
2026-05-28T12:17:50.290105+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970670290_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12121 on JY-20963-fix-import-on-deleted-entity, menu","depth":5,"on_screen":true,"help_text":"Pull request #12121 exists for current branch JY-20963-fix-import-on-deleted-entity","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
6879326690315022146
|
-8631728821509045824
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"X4‹$0(ah]A100% <78• Thu 28 May 15:17:50181ec2-user@ip-10-30-140-...₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85311
|
NULL
|
NULL
|
NULL
|
|
85311
|
2920
|
34
|
2026-05-28T12:17:46.559275+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970666559_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes
Hide This Notification
Code changed:
Hide
45
1
41
66
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.own...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12121 on JY-20963-fix-import-on-deleted-entity, menu","depth":5,"on_screen":true,"help_text":"Pull request #12121 exists for current branch JY-20963-fix-import-on-deleted-entity","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"TextRelayServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"45","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"41","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"66","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01';\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');\n\n# ***************\nSELECT DISTINCT u.id, u.email, u.name, u.softphone_number, COUNT(a.id) as sms_count\nFROM users u\nINNER JOIN activities a ON u.id = .user_id\nWHERE a.type LIKE 'sms%'\nAND a.created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)\nGROUP BY u.id, u.email, u.name, u.softphone_number\nORDER BY sms_count DESC;\n\nselect * from teams where id = 1;\n\nselect * from roles;\n\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1117 and sa.provider = 'hubspot';\nSELECT * FROM activities WHERE uuid_to_bin('8024fffb-2df7-4017-91f4-d9f896050248') = uuid; # 79933459 YES\nSELECT * FROM activities WHERE uuid_to_bin('25529043-8094-4781-927f-4f4da2a8185c') = uuid; # 80186192 NO\nSELECT * FROM crm_configurations WHERE id = 1053;\nSELECT * FROM teams WHERE id = 1117;\nselect * from users where id = 30249;\nselect * from playbooks where id = 5473;\nselect * from playbook_categories where id = 43783;\nselect * from playbook_categories where playbook_id = 5473;\nselect * from crm_fields where id = 659242;\nselect * from crm_field_values where crm_field_id = 659242;\n\nSELECT * FROM crm_field_data fd\n# JOIN crm_fields f ON fd.crm_field_id = f.id\n# JOIN activities a ON fd.activity_id = a.id\nWHERE activity_id = 79933459\n# AND f.crm_provider_id = 'hs_activity_type';\n\n\nSELECT * FROM activity_messages;\nselect * from text_relays where created_at > '2026-05-01';\nselect * from activities where user_id IN (7160, 18608) and created_at > '2026-05-22' order by id desc;\nselect * from users where team_id = 1 and id IN (18608, 13934, 7160);\nselect * from activities where user_id = 7160 order by id desc limit 10;\n\nselect * from accounts where team_id = 1 and name = 'Column5';\n\nselect * from users where name like '%Subra%'; # 31054, 1117\nselect * from teams where id = 1117;\nselect * from activity_searches where user_id = 31054;\nselect * from activity_search_filters where activity_search_id IN (88882, 88902);","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01';\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');\n\n# ***************\nSELECT DISTINCT u.id, u.email, u.name, u.softphone_number, COUNT(a.id) as sms_count\nFROM users u\nINNER JOIN activities a ON u.id = .user_id\nWHERE a.type LIKE 'sms%'\nAND a.created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)\nGROUP BY u.id, u.email, u.name, u.softphone_number\nORDER BY sms_count DESC;\n\nselect * from teams where id = 1;\n\nselect * from roles;\n\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1117 and sa.provider = 'hubspot';\nSELECT * FROM activities WHERE uuid_to_bin('8024fffb-2df7-4017-91f4-d9f896050248') = uuid; # 79933459 YES\nSELECT * FROM activities WHERE uuid_to_bin('25529043-8094-4781-927f-4f4da2a8185c') = uuid; # 80186192 NO\nSELECT * FROM crm_configurations WHERE id = 1053;\nSELECT * FROM teams WHERE id = 1117;\nselect * from users where id = 30249;\nselect * from playbooks where id = 5473;\nselect * from playbook_categories where id = 43783;\nselect * from playbook_categories where playbook_id = 5473;\nselect * from crm_fields where id = 659242;\nselect * from crm_field_values where crm_field_id = 659242;\n\nSELECT * FROM crm_field_data fd\n# JOIN crm_fields f ON fd.crm_field_id = f.id\n# JOIN activities a ON fd.activity_id = a.id\nWHERE activity_id = 79933459\n# AND f.crm_provider_id = 'hs_activity_type';\n\n\nSELECT * FROM activity_messages;\nselect * from text_relays where created_at > '2026-05-01';\nselect * from activities where user_id IN (7160, 18608) and created_at > '2026-05-22' order by id desc;\nselect * from users where team_id = 1 and id IN (18608, 13934, 7160);\nselect * from activities where user_id = 7160 order by id desc limit 10;\n\nselect * from accounts where team_id = 1 and name = 'Column5';\n\nselect * from users where name like '%Subra%'; # 31054, 1117\nselect * from teams where id = 1117;\nselect * from activity_searches where user_id = 31054;\nselect * from activity_search_filters where activity_search_id IN (88882, 88902);","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
2526630547225287665
|
1137771414947247693
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes
Hide This Notification
Code changed:
Hide
45
1
41
66
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.own...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85310
|
2921
|
35
|
2026-05-28T12:17:46.455990+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970666455_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12121 on JY-20963-fix-import-on-deleted-entity, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.11569149,"height":0.025538707},"on_screen":true,"help_text":"Pull request #12121 exists for current branch JY-20963-fix-import-on-deleted-entity","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8374335,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12","depth":4,"bounds":{"left":0.37865692,"top":0.15003991,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"bounds":{"left":0.39029256,"top":0.15003991,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39993352,"top":0.14844373,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40724733,"top":0.14844373,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41589096,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.4245346,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.43550533,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44414893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.45279256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.4637633,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47473404,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.5013298,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.51230055,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
490348651913652116
|
-30141114868883220
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes...
|
85309
|
NULL
|
NULL
|
NULL
|
|
85309
|
2921
|
34
|
2026-05-28T12:17:45.571937+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970665571_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes
Hide This Notification
Code changed:
Hide
45
1
41
66
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.own...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12121 on JY-20963-fix-import-on-deleted-entity, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.11569149,"height":0.025538707},"on_screen":true,"help_text":"Pull request #12121 exists for current branch JY-20963-fix-import-on-deleted-entity","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8374335,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"TextRelayServiceTest","depth":6,"bounds":{"left":0.85272604,"top":0.019952115,"width":0.062832445,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'TextRelayServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'TextRelayServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12","depth":4,"bounds":{"left":0.37865692,"top":0.15003991,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"9","depth":4,"bounds":{"left":0.39029256,"top":0.15003991,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39993352,"top":0.14844373,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40724733,"top":0.14844373,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Journal;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\Webhook\\WebhookEventProcessor;\n\nclass HubspotJournalPollingService\n{\n private const string OFFSET_CACHE_KEY = 'hubspot_journal_offset';\n private const string POLLING_LOCK_KEY = 'hubspot_journal_polling_lock';\n private const string STOP_FLAG_KEY = 'hubspot_journal_stop_flag';\n private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds\n private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds\n private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data\n private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration\n private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep\n private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping\n private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit\n private const int MAX_BACKOFF_SECONDS = 300;\n private const int MAX_OFFSET_RETRIES = 3;\n private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes\n private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;\n private const int LOG_INTERVAL_CYCLES = 10;\n\n private bool $shouldStop = false;\n private int $consecutiveEmptyResults = 0;\n private array $offsetRetryCount = [];\n\n private int $cycleCount = 0;\n private int $startTime = 0;\n private int $lastLockRenewal = 0;\n\n private float $totalApiTime = 0;\n private float $totalDownloadTime = 0;\n private float $totalTransformTime = 0;\n private float $totalProcessTime = 0;\n\n private int $totalJournalFilesDownloaded = 0;\n private int $totalEventsProcessed = 0;\n private int $emptyJournalFiles = 0;\n private int $otherPortalSkipped = 0;\n\n public function __construct(\n private HubspotJournalApiClient $apiClient,\n private JournalEventTransformer $transformer,\n private WebhookEventProcessor $eventProcessor\n ) {\n }\n\n /**\n * Start continuous polling of the HubSpot journal\n */\n public function startPolling(): void\n {\n $this->startTime = time();\n $this->cycleCount = 0;\n $this->logPollingStart();\n\n if (! $this->acquirePollingLock()) {\n Log::warning('[HubSpot Journal Polling] Another polling process is already running');\n\n return;\n }\n\n try {\n while ($this->shouldContinuePolling()) {\n $this->cycleCount++;\n $this->executePollingCycle();\n }\n } catch (\\Throwable $e) {\n Log::error('[HubSpot Journal Polling] Error while polling', [\n 'error' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n } finally {\n $this->cleanupPollingSession();\n }\n }\n\n /**\n * Perform a single polling cycle\n * Returns true if work was found and processed, false if no work available, null if entry was skipped\n */\n public function pollOnce(): ?bool\n {\n $currentOffset = $this->getCurrentOffset();\n\n $apiStart = microtime(true);\n $apiResult = $currentOffset === null\n ? $this->apiClient->getLatestJournalEntry()\n : $this->apiClient->getNextJournalEntry($currentOffset);\n $this->totalApiTime += (microtime(true) - $apiStart) * 1000;\n\n if (! $apiResult->success) {\n return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');\n }\n\n if ($apiResult->data === null) {\n Log::info('[HubSpot Journal Polling] No data');\n\n return false;\n }\n\n $offset = $apiResult->data['currentOffset'];\n $s3Url = $apiResult->data['url'];\n $retryCount = $this->offsetRetryCount[$offset] ?? 0;\n\n $downloadStart = microtime(true);\n $downloadResult = $this->apiClient->downloadJournalFile($s3Url);\n $this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;\n\n if (! $downloadResult->success) {\n return $this->handleDownloadResult($downloadResult, $offset, $retryCount);\n }\n\n $this->totalJournalFilesDownloaded++;\n $journalData = $downloadResult->data;\n\n $transformStart = microtime(true);\n\n try {\n $transformedEvents = $this->transformer->transformJournalEvents($journalData);\n } catch (\\Exception $e) {\n return $this->handleTransformationFailure($offset, $retryCount, $e);\n }\n $this->totalTransformTime += (microtime(true) - $transformStart) * 1000;\n unset($journalData);\n\n $processStart = microtime(true);\n $eventsCount = count($transformedEvents);\n $this->totalEventsProcessed += $eventsCount;\n\n if ($eventsCount === 0) {\n $this->emptyJournalFiles++;\n } else {\n $this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');\n }\n $this->totalProcessTime += (microtime(true) - $processStart) * 1000;\n\n $this->updateOffset($offset);\n unset($transformedEvents);\n\n $this->logProgressIfNeeded();\n\n return $eventsCount > 0;\n }\n\n private function logProgressIfNeeded(): void\n {\n if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {\n return;\n }\n\n $cycles = $this->cycleCount;\n $avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;\n\n Log::info('[HubSpot Journal Polling] Progress', [\n 'cycles' => $cycles,\n 'files' => $this->totalJournalFilesDownloaded,\n 'events' => $this->totalEventsProcessed,\n 'empty_files' => $this->emptyJournalFiles,\n 'avg_ms' => round($avgTotal, 1),\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n ]);\n }\n\n /**\n * Get the current polling offset from Redis\n */\n private function getCurrentOffset(bool $cacheOnly = false): ?string\n {\n $offset = Redis::get(self::OFFSET_CACHE_KEY);\n\n if (! $offset && ! $cacheOnly) {\n $offset = $this->getDbOffset();\n }\n\n return $offset ? (string) $offset : null;\n }\n\n /**\n * Get the last stored offset from the database\n */\n public function getDbOffset(): ?string\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return null;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');\n\n Log::info('[HubSpot Journal Polling] Getting offset from database', [\n 'offset' => $offset,\n 'jiminny_team_id' => $jiminnyTeam->getId(),\n ]);\n\n return $offset;\n }\n\n /**\n * Reset the database offset\n */\n public function resetDbOffset(): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');\n\n Log::info('[HubSpot Journal Polling] Database offset reset');\n }\n\n private function getJiminnyTeam(): ?Team\n {\n $teamRepository = app(TeamRepository::class);\n\n return $teamRepository->getTeamBySlug('jiminny');\n }\n\n private function updateDbOffset(string $offset): void\n {\n $jiminnyTeam = $this->getJiminnyTeam();\n\n if (! $jiminnyTeam instanceof Team) {\n Log::error('[HubSpot Journal Polling] Jiminny team not found');\n\n return;\n }\n\n $crmRepository = app(CrmConfigurationRepository::class);\n\n $crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);\n }\n\n /**\n * Update the polling offset\n */\n private function updateOffset(string $offset): void\n {\n Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL\n $this->clearOffsetRetryCount($offset);\n }\n\n /**\n * Reset the polling offset\n */\n public function resetOffset(): void\n {\n Redis::del(self::OFFSET_CACHE_KEY);\n Log::info('[HubSpot Journal Polling] Reset polling offset');\n }\n\n /**\n * Set a specific offset (for manual override or recovery)\n */\n public function setOffset(string $offset): void\n {\n $this->updateOffset($offset);\n\n Log::warning('[HubSpot Journal Polling] Offset manually set', [\n 'offset' => $offset,\n ]);\n }\n\n /**\n * Get current polling status\n */\n public function getPollingStatus(): array\n {\n $lockDataJson = Redis::get(self::POLLING_LOCK_KEY);\n $lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;\n\n return [\n 'is_locked' => $lockData !== null,\n 'current_offset' => $this->getCurrentOffset(),\n 'lock_expires_at' => $lockData['expires_at'] ?? null,\n 'lock_acquired_at' => $lockData['acquired_at'] ?? null,\n ];\n }\n\n /**\n * Acquire exclusive polling lock to prevent multiple instances\n */\n private function acquirePollingLock(): bool\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n // Use atomic operation to set both lock and expiration data\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n ];\n\n // Use SETNX (SET if Not eXists) for atomic lock acquisition\n $lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');\n\n if ($lockAcquired) {\n $this->lastLockRenewal = time();\n Log::info('[HubSpot Journal Polling] Acquired polling lock', [\n 'expires_at' => $expiresAt,\n ]);\n }\n\n return (bool) $lockAcquired;\n }\n\n /**\n * Release the polling lock\n */\n private function releasePollingLock(): void\n {\n Redis::del(self::POLLING_LOCK_KEY);\n Log::info('[HubSpot Journal Polling] Released polling lock');\n }\n\n /**\n * Force release the polling lock (for emergency situations)\n */\n public function forceReleaseLock(): void\n {\n $this->releasePollingLock();\n Log::warning('[HubSpot Journal Polling] Force released polling lock');\n }\n\n /**\n * Signal the polling service to stop gracefully\n */\n public function requestStop(): void\n {\n Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL\n $this->shouldStop = true;\n Log::info('[HubSpot Journal Polling] Stop requested');\n }\n\n /**\n * Check if polling should stop\n */\n private function shouldStop(): bool\n {\n // Check local flag first (faster)\n if ($this->shouldStop) {\n return true;\n }\n\n // Check Redis flag (for external stop requests)\n if (Redis::exists(self::STOP_FLAG_KEY)) {\n $this->shouldStop = true;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Clear the stop flag and reset state to allow service to start\n */\n public function clearStopFlag(): void\n {\n Redis::del(self::STOP_FLAG_KEY);\n $this->shouldStop = false;\n $this->resetPollingState();\n\n Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');\n }\n\n /**\n * Reset polling state without clearing stop flag\n */\n private function resetPollingState(): void\n {\n $this->consecutiveEmptyResults = 0;\n $this->cycleCount = 0;\n $this->startTime = 0;\n $this->totalApiTime = 0;\n $this->totalDownloadTime = 0;\n $this->totalTransformTime = 0;\n $this->totalProcessTime = 0;\n $this->totalJournalFilesDownloaded = 0;\n $this->totalEventsProcessed = 0;\n $this->emptyJournalFiles = 0;\n $this->otherPortalSkipped = 0;\n }\n\n public function hasStopFlag(): bool\n {\n return (bool) Redis::exists(self::STOP_FLAG_KEY);\n }\n\n /**\n * Calculate adaptive sleep duration based on consecutive empty results\n */\n private function calculateAdaptiveSleep(): int\n {\n if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {\n return self::BASE_SLEEP_SECONDS; // 5 second\n }\n\n // Progressive backoff: 15s -> 30s -> 60s -> 120s (max)\n $delay = 3 * self::BASE_SLEEP_SECONDS;\n $sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));\n\n return min($sleepDuration, self::MAX_SLEEP_SECONDS);\n }\n\n private function logPollingStart(): void\n {\n Log::info('[HubSpot Journal Polling] Service starting', [\n 'memory_limit' => ini_get('memory_limit'),\n 'max_execution_time' => ini_get('max_execution_time'),\n 'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Log polling service end information\n */\n private function logPollingEnd(): void\n {\n $runtime = time() - $this->startTime;\n $cycles = max($this->cycleCount, 1);\n\n Log::info('[HubSpot Journal Polling] Service ending', [\n 'runtime_seconds' => $runtime,\n 'total_cycles' => $this->cycleCount,\n 'files_downloaded' => $this->totalJournalFilesDownloaded,\n 'empty_files' => $this->emptyJournalFiles,\n 'other_portal_skipped' => $this->otherPortalSkipped,\n 'total_events' => $this->totalEventsProcessed,\n 'events_per_file' => $this->totalJournalFilesDownloaded > 0\n ? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)\n : 0,\n 'avg_api_ms' => round($this->totalApiTime / $cycles, 1),\n 'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),\n 'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),\n 'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),\n 'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),\n ]);\n }\n\n /**\n * Improved stop condition check with clear reasoning\n */\n private function shouldContinuePolling(): bool\n {\n // Check explicit stop request first (fastest check)\n if ($this->shouldStop()) {\n Log::info('[HubSpot Journal Polling] Stop requested, ending polling');\n\n return false;\n }\n\n if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {\n Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [\n 'empty_results' => $this->consecutiveEmptyResults,\n 'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,\n ]);\n\n return false;\n }\n\n // Check runtime limit (4 minutes)\n $runtime = time() - $this->startTime;\n if ($runtime >= self::MAX_RUNTIME_SECONDS) {\n Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [\n 'runtime_seconds' => $runtime,\n 'runtime_minutes' => round($runtime / 60, 1),\n 'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,\n ]);\n\n return false;\n }\n\n // Check memory limits (prevent OOM)\n $currentMemory = memory_get_usage(true);\n $memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));\n\n if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {\n Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [\n 'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),\n 'memory_limit' => ini_get('memory_limit'),\n 'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),\n ]);\n\n return false;\n }\n\n // Check for excessive cycles (prevent runaway processes)\n if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {\n Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [\n 'cycles' => $this->cycleCount,\n 'max_cycles' => self::MAX_CYCLES_DEFAULT,\n ]);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Handle when work is found - reset counters and continue immediately\n */\n private function handleWorkFound(): void\n {\n $this->consecutiveEmptyResults = 0;\n }\n\n /**\n * Handle when no work is found - implement adaptive sleep\n */\n private function handleNoWorkFound(): void\n {\n $this->consecutiveEmptyResults++;\n $sleepDuration = $this->calculateAdaptiveSleep();\n\n Log::debug('[HubSpot Journal Polling] No work found, sleeping', [\n 'consecutive_empty' => $this->consecutiveEmptyResults,\n 'sleep_seconds' => $sleepDuration,\n 'cycle' => $this->cycleCount,\n ]);\n\n $this->responsiveSleep($sleepDuration);\n }\n\n /**\n * Sleep with responsive stop checking\n */\n private function responsiveSleep(int $seconds): void\n {\n for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {\n sleep(1);\n }\n }\n\n /**\n * Parse memory limit string to bytes\n */\n private function parseMemoryLimit(string $memoryLimit): int\n {\n if ($memoryLimit === '-1') {\n return 0; // Unlimited\n }\n\n $unit = strtolower(substr($memoryLimit, -1));\n $value = (int) substr($memoryLimit, 0, -1);\n\n return match ($unit) {\n 'g' => $value * 1024 * 1024 * 1024,\n 'm' => $value * 1024 * 1024,\n 'k' => $value * 1024,\n default => (int) $memoryLimit,\n };\n }\n\n private function executePollingCycle(): void\n {\n $this->renewLockIfNeeded();\n\n $result = $this->pollOnce();\n\n if ($result === true) {\n $this->handleWorkFound();\n } elseif ($result === false) {\n $this->handleNoWorkFound();\n }\n }\n\n private function renewLockIfNeeded(): void\n {\n $now = time();\n if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {\n $this->renewPollingLock();\n $this->lastLockRenewal = $now;\n }\n }\n\n private function renewPollingLock(): void\n {\n $expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();\n\n $lockData = [\n 'locked' => true,\n 'expires_at' => $expiresAt,\n 'acquired_at' => now()->toISOString(),\n 'renewed_at' => now()->toISOString(),\n 'cycle' => $this->cycleCount,\n ];\n\n Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));\n\n Log::debug('[HubSpot Journal Polling] Lock renewed', [\n 'expires_at' => $expiresAt,\n 'cycle' => $this->cycleCount,\n ]);\n }\n\n private function handleApiResult(JournalApiResult $result, string $context): bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_AUTH) {\n Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [\n 'context' => $context,\n ]);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {\n $waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);\n Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [\n 'wait_seconds' => $waitSeconds,\n ]);\n $this->responsiveSleep($waitSeconds);\n\n return false;\n }\n\n if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {\n Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [\n 'expired_offset' => $context,\n ]);\n $this->resetOffset();\n $this->resetDbOffset();\n\n return false;\n }\n\n if ($result->isPermanentFailure()) {\n Log::error('[HubSpot Journal Polling] Permanent API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->shouldStop = true;\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable API failure', [\n 'context' => $context,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Clean up polling session resources\n */\n private function cleanupPollingSession(): void\n {\n $this->logPollingEnd();\n $this->storeOffsetInDB();\n $this->releasePollingLock();\n $this->apiClient->clearPortalCache();\n $this->resetPollingState();\n }\n\n private function storeOffsetInDB(): void\n {\n // Save current offset to database before cleanup\n $currentOffset = $this->getCurrentOffset(cacheOnly: true);\n if ($currentOffset) {\n $this->updateDbOffset($currentOffset);\n\n Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [\n 'offset' => $currentOffset,\n ]);\n }\n }\n\n private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool\n {\n if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {\n $this->otherPortalSkipped++;\n $this->updateOffset($offset);\n\n return null;\n }\n\n if ($result->isPermanentFailure()) {\n Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'error' => $result->errorMessage,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [\n 'offset' => $offset,\n 'portal_id' => $result->portalId,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n ]);\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [\n 'offset' => $offset,\n 'failure_type' => $result->failureType,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n if ($result->retryAfterSeconds) {\n sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));\n }\n\n return false;\n }\n\n /**\n * Handle transformation failure with retry logic\n */\n private function handleTransformationFailure(string $offset, int $retryCount, \\Exception $exception): bool\n {\n $retryCount++;\n\n if ($retryCount >= self::MAX_OFFSET_RETRIES) {\n Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'error' => $exception->getMessage(),\n 'trace' => $exception->getTraceAsString(),\n ]);\n\n // Skip this offset to prevent infinite loop with corrupted data\n $this->updateOffset($offset);\n $this->clearOffsetRetryCount($offset);\n\n return false;\n }\n\n Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [\n 'offset' => $offset,\n 'retry_count' => $retryCount,\n 'max_retries' => self::MAX_OFFSET_RETRIES,\n 'error' => $exception->getMessage(),\n ]);\n\n $this->offsetRetryCount[$offset] = $retryCount;\n\n return false;\n }\n\n /**\n * Clear retry count for an offset after successful processing\n */\n private function clearOffsetRetryCount(string $offset): void\n {\n unset($this->offsetRetryCount[$offset]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.41589096,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.4245346,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.43550533,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.44414893,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.45279256,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.4637633,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.47473404,"top":0.09896249,"width":0.024268618,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.5013298,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.51230055,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7237367,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"45","depth":4,"bounds":{"left":0.6938165,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.70611703,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"41","depth":4,"bounds":{"left":0.71542555,"top":0.123703115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"66","depth":4,"bounds":{"left":0.72706115,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7390292,"top":0.12210695,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7463431,"top":0.12210695,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01';\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');\n\n# ***************\nSELECT DISTINCT u.id, u.email, u.name, u.softphone_number, COUNT(a.id) as sms_count\nFROM users u\nINNER JOIN activities a ON u.id = .user_id\nWHERE a.type LIKE 'sms%'\nAND a.created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)\nGROUP BY u.id, u.email, u.name, u.softphone_number\nORDER BY sms_count DESC;\n\nselect * from teams where id = 1;\n\nselect * from roles;\n\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1117 and sa.provider = 'hubspot';\nSELECT * FROM activities WHERE uuid_to_bin('8024fffb-2df7-4017-91f4-d9f896050248') = uuid; # 79933459 YES\nSELECT * FROM activities WHERE uuid_to_bin('25529043-8094-4781-927f-4f4da2a8185c') = uuid; # 80186192 NO\nSELECT * FROM crm_configurations WHERE id = 1053;\nSELECT * FROM teams WHERE id = 1117;\nselect * from users where id = 30249;\nselect * from playbooks where id = 5473;\nselect * from playbook_categories where id = 43783;\nselect * from playbook_categories where playbook_id = 5473;\nselect * from crm_fields where id = 659242;\nselect * from crm_field_values where crm_field_id = 659242;\n\nSELECT * FROM crm_field_data fd\n# JOIN crm_fields f ON fd.crm_field_id = f.id\n# JOIN activities a ON fd.activity_id = a.id\nWHERE activity_id = 79933459\n# AND f.crm_provider_id = 'hs_activity_type';\n\n\nSELECT * FROM activity_messages;\nselect * from text_relays where created_at > '2026-05-01';\nselect * from activities where user_id IN (7160, 18608) and created_at > '2026-05-22' order by id desc;\nselect * from users where team_id = 1 and id IN (18608, 13934, 7160);\nselect * from activities where user_id = 7160 order by id desc limit 10;\n\nselect * from accounts where team_id = 1 and name = 'Column5';\n\nselect * from users where name like '%Subra%'; # 31054, 1117\nselect * from teams where id = 1117;\nselect * from activity_searches where user_id = 31054;\nselect * from activity_search_filters where activity_search_id IN (88882, 88902);","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\n\nselect * from text_relays where created_at > '2026-05-01';\nand id IN (32415, 32416);\n# and id = 32412;\n\nselect * from users where team_id = 2 and email like '%scott%' and id = 29510;\n\nSELECT * FROM activities WHERE uuid_to_bin('67cebfc2-ed56-44a2-8c68-7a0286ed8618') = uuid; # 79763436\n\nSELECT email_provider_id, COUNT(*) as count, GROUP_CONCAT(id) as ids, GROUP_CONCAT(status) as statuses\nFROM text_relays\nWHERE email_provider_id IN ('19e2027868a64b42', '19e2033ed8ea6b10')\nGROUP BY email_provider_id;\nSELECT id, status, telephony_provider_id, created_at\nFROM activities\nWHERE id IN (80028719, 80028846);\nSELECT id, status, code, email_sent_at, created_at, updated_at\nFROM text_relays\nWHERE id IN (32415, 32416);\nSELECT id, status, code, sender, recipient, created_at\nFROM text_relays\nWHERE sender LIKE '%mario.georgiev%' OR sender LIKE '%stoyan.tomov%'\nORDER BY created_at DESC\nLIMIT 10;\n\nSELECT id, uuid, status, code, sender, recipient, created_at, updated_at\nFROM text_relays\nWHERE uuid = uuid_to_bin('0626141c-27a6-4d8c-aff8-7c8020a2c656');\n\n# ***************\nSELECT DISTINCT u.id, u.email, u.name, u.softphone_number, COUNT(a.id) as sms_count\nFROM users u\nINNER JOIN activities a ON u.id = .user_id\nWHERE a.type LIKE 'sms%'\nAND a.created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)\nGROUP BY u.id, u.email, u.name, u.softphone_number\nORDER BY sms_count DESC;\n\nselect * from teams where id = 1;\n\nselect * from roles;\n\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1117 and sa.provider = 'hubspot';\nSELECT * FROM activities WHERE uuid_to_bin('8024fffb-2df7-4017-91f4-d9f896050248') = uuid; # 79933459 YES\nSELECT * FROM activities WHERE uuid_to_bin('25529043-8094-4781-927f-4f4da2a8185c') = uuid; # 80186192 NO\nSELECT * FROM crm_configurations WHERE id = 1053;\nSELECT * FROM teams WHERE id = 1117;\nselect * from users where id = 30249;\nselect * from playbooks where id = 5473;\nselect * from playbook_categories where id = 43783;\nselect * from playbook_categories where playbook_id = 5473;\nselect * from crm_fields where id = 659242;\nselect * from crm_field_values where crm_field_id = 659242;\n\nSELECT * FROM crm_field_data fd\n# JOIN crm_fields f ON fd.crm_field_id = f.id\n# JOIN activities a ON fd.activity_id = a.id\nWHERE activity_id = 79933459\n# AND f.crm_provider_id = 'hs_activity_type';\n\n\nSELECT * FROM activity_messages;\nselect * from text_relays where created_at > '2026-05-01';\nselect * from activities where user_id IN (7160, 18608) and created_at > '2026-05-22' order by id desc;\nselect * from users where team_id = 1 and id IN (18608, 13934, 7160);\nselect * from activities where user_id = 7160 order by id desc limit 10;\n\nselect * from accounts where team_id = 1 and name = 'Column5';\n\nselect * from users where name like '%Subra%'; # 31054, 1117\nselect * from teams where id = 1117;\nselect * from activity_searches where user_id = 31054;\nselect * from activity_search_filters where activity_search_id IN (88882, 88902);","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
2526630547225287665
|
1137771414947247693
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12121 on JY-20963-fix-im Project: faVsco.js, menu
#12121 on JY-20963-fix-import-on-deleted-entity, menu
Start Listening for PHP Debug Connections
TextRelayServiceTest
Run 'TextRelayServiceTest'
Debug 'TextRelayServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
12
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Journal;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Jiminny\Models\Team;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Services\Crm\Hubspot\Webhook\WebhookEventProcessor;
class HubspotJournalPollingService
{
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const string [ENV_SECRET];
private const int LOCK_TTL_SECONDS = 120; // 2 minutes - renewed every 30 seconds
private const int LOCK_RENEWAL_INTERVAL = 30; // Renew lock every 30 seconds
private const int BASE_SLEEP_SECONDS = 5; // Base sleep when no data
private const int MAX_SLEEP_SECONDS = 120; // Maximum sleep duration
private const int EMPTY_THRESHOLD_FOR_BACKOFF = 3; // Empty results before increasing sleep
private const int MAX_CYCLES_DEFAULT = 3000; // Default maximum cycles before stopping
private const int MEMORY_CRITICAL_THRESHOLD = 90; // 90% of memory limit
private const int MAX_BACKOFF_SECONDS = 300;
private const int MAX_OFFSET_RETRIES = 3;
private const int MAX_RUNTIME_SECONDS = 240; // 4 minutes
private const int MAX_EMPTY_RESULTS_BEFORE_EXIT = 5;
private const int LOG_INTERVAL_CYCLES = 10;
private bool $shouldStop = false;
private int $consecutiveEmptyResults = 0;
private array $offsetRetryCount = [];
private int $cycleCount = 0;
private int $startTime = 0;
private int $lastLockRenewal = 0;
private float $totalApiTime = 0;
private float $totalDownloadTime = 0;
private float $totalTransformTime = 0;
private float $totalProcessTime = 0;
private int $totalJournalFilesDownloaded = 0;
private int $totalEventsProcessed = 0;
private int $emptyJournalFiles = 0;
private int $otherPortalSkipped = 0;
public function __construct(
private HubspotJournalApiClient $apiClient,
private JournalEventTransformer $transformer,
private WebhookEventProcessor $eventProcessor
) {
}
/**
* Start continuous polling of the HubSpot journal
*/
public function startPolling(): void
{
$this->startTime = time();
$this->cycleCount = 0;
$this->logPollingStart();
if (! $this->acquirePollingLock()) {
Log::warning('[HubSpot Journal Polling] Another polling process is already running');
return;
}
try {
while ($this->shouldContinuePolling()) {
$this->cycleCount++;
$this->executePollingCycle();
}
} catch (\Throwable $e) {
Log::error('[HubSpot Journal Polling] Error while polling', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
} finally {
$this->cleanupPollingSession();
}
}
/**
* Perform a single polling cycle
* Returns true if work was found and processed, false if no work available, null if entry was skipped
*/
public function pollOnce(): ?bool
{
$currentOffset = $this->getCurrentOffset();
$apiStart = microtime(true);
$apiResult = $currentOffset === null
? $this->apiClient->getLatestJournalEntry()
: $this->apiClient->getNextJournalEntry($currentOffset);
$this->totalApiTime += (microtime(true) - $apiStart) * 1000;
if (! $apiResult->success) {
return $this->handleApiResult($apiResult, $currentOffset ?? 'latest');
}
if ($apiResult->data === null) {
Log::info('[HubSpot Journal Polling] No data');
return false;
}
$offset = $apiResult->data['currentOffset'];
$s3Url = $apiResult->data['url'];
$retryCount = $this->offsetRetryCount[$offset] ?? 0;
$downloadStart = microtime(true);
$downloadResult = $this->apiClient->downloadJournalFile($s3Url);
$this->totalDownloadTime += (microtime(true) - $downloadStart) * 1000;
if (! $downloadResult->success) {
return $this->handleDownloadResult($downloadResult, $offset, $retryCount);
}
$this->totalJournalFilesDownloaded++;
$journalData = $downloadResult->data;
$transformStart = microtime(true);
try {
$transformedEvents = $this->transformer->transformJournalEvents($journalData);
} catch (\Exception $e) {
return $this->handleTransformationFailure($offset, $retryCount, $e);
}
$this->totalTransformTime += (microtime(true) - $transformStart) * 1000;
unset($journalData);
$processStart = microtime(true);
$eventsCount = count($transformedEvents);
$this->totalEventsProcessed += $eventsCount;
if ($eventsCount === 0) {
$this->emptyJournalFiles++;
} else {
$this->eventProcessor->processEvents($transformedEvents, '[HubSpot Journal Polling]');
}
$this->totalProcessTime += (microtime(true) - $processStart) * 1000;
$this->updateOffset($offset);
unset($transformedEvents);
$this->logProgressIfNeeded();
return $eventsCount > 0;
}
private function logProgressIfNeeded(): void
{
if ($this->cycleCount === 0 || $this->cycleCount % self::LOG_INTERVAL_CYCLES !== 0) {
return;
}
$cycles = $this->cycleCount;
$avgTotal = ($this->totalApiTime + $this->totalDownloadTime + $this->totalTransformTime + $this->totalProcessTime) / $cycles;
Log::info('[HubSpot Journal Polling] Progress', [
'cycles' => $cycles,
'files' => $this->totalJournalFilesDownloaded,
'events' => $this->totalEventsProcessed,
'empty_files' => $this->emptyJournalFiles,
'avg_ms' => round($avgTotal, 1),
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
]);
}
/**
* Get the current polling offset from Redis
*/
private function getCurrentOffset(bool $cacheOnly = false): ?string
{
$offset = Redis::get(self::OFFSET_CACHE_KEY);
if (! $offset && ! $cacheOnly) {
$offset = $this->getDbOffset();
}
return $offset ? (string) $offset : null;
}
/**
* Get the last stored offset from the database
*/
public function getDbOffset(): ?string
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return null;
}
$crmRepository = app(CrmConfigurationRepository::class);
$offset = $crmRepository->getSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset');
Log::info('[HubSpot Journal Polling] Getting offset from database', [
'offset' => $offset,
'jiminny_team_id' => $jiminnyTeam->getId(),
]);
return $offset;
}
/**
* Reset the database offset
*/
public function resetDbOffset(): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', '');
Log::info('[HubSpot Journal Polling] Database offset reset');
}
private function getJiminnyTeam(): ?Team
{
$teamRepository = app(TeamRepository::class);
return $teamRepository->getTeamBySlug('jiminny');
}
private function updateDbOffset(string $offset): void
{
$jiminnyTeam = $this->getJiminnyTeam();
if (! $jiminnyTeam instanceof Team) {
Log::error('[HubSpot Journal Polling] Jiminny team not found');
return;
}
$crmRepository = app(CrmConfigurationRepository::class);
$crmRepository->updateSetting($jiminnyTeam->getCrmConfiguration(), 'hubspot_journal_offset', $offset);
}
/**
* Update the polling offset
*/
private function updateOffset(string $offset): void
{
Redis::setex(self::OFFSET_CACHE_KEY, 259200, $offset); // 3 days TTL
$this->clearOffsetRetryCount($offset);
}
/**
* Reset the polling offset
*/
public function resetOffset(): void
{
Redis::del(self::OFFSET_CACHE_KEY);
Log::info('[HubSpot Journal Polling] Reset polling offset');
}
/**
* Set a specific offset (for manual override or recovery)
*/
public function setOffset(string $offset): void
{
$this->updateOffset($offset);
Log::warning('[HubSpot Journal Polling] Offset manually set', [
'offset' => $offset,
]);
}
/**
* Get current polling status
*/
public function getPollingStatus(): array
{
$lockDataJson = Redis::get(self::POLLING_LOCK_KEY);
$lockData = $lockDataJson ? json_decode($lockDataJson, true) : null;
return [
'is_locked' => $lockData !== null,
'current_offset' => $this->getCurrentOffset(),
'lock_expires_at' => $lockData['expires_at'] ?? null,
'lock_acquired_at' => $lockData['acquired_at'] ?? null,
];
}
/**
* Acquire exclusive polling lock to prevent multiple instances
*/
private function acquirePollingLock(): bool
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
// Use atomic operation to set both lock and expiration data
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
];
// Use SETNX (SET if Not eXists) for atomic lock acquisition
$lockAcquired = Redis::set(self::POLLING_LOCK_KEY, json_encode($lockData), 'EX', self::LOCK_TTL_SECONDS, 'NX');
if ($lockAcquired) {
$this->lastLockRenewal = time();
Log::info('[HubSpot Journal Polling] Acquired polling lock', [
'expires_at' => $expiresAt,
]);
}
return (bool) $lockAcquired;
}
/**
* Release the polling lock
*/
private function releasePollingLock(): void
{
Redis::del(self::POLLING_LOCK_KEY);
Log::info('[HubSpot Journal Polling] Released polling lock');
}
/**
* Force release the polling lock (for emergency situations)
*/
public function forceReleaseLock(): void
{
$this->releasePollingLock();
Log::warning('[HubSpot Journal Polling] Force released polling lock');
}
/**
* Signal the polling service to stop gracefully
*/
public function requestStop(): void
{
Redis::setex(self::STOP_FLAG_KEY, 300, '1'); // 5 minutes TTL
$this->shouldStop = true;
Log::info('[HubSpot Journal Polling] Stop requested');
}
/**
* Check if polling should stop
*/
private function shouldStop(): bool
{
// Check local flag first (faster)
if ($this->shouldStop) {
return true;
}
// Check Redis flag (for external stop requests)
if (Redis::exists(self::STOP_FLAG_KEY)) {
$this->shouldStop = true;
return true;
}
return false;
}
/**
* Clear the stop flag and reset state to allow service to start
*/
public function clearStopFlag(): void
{
Redis::del(self::STOP_FLAG_KEY);
$this->shouldStop = false;
$this->resetPollingState();
Log::info('[HubSpot Journal Polling] Stop flag cleared and state reset');
}
/**
* Reset polling state without clearing stop flag
*/
private function resetPollingState(): void
{
$this->consecutiveEmptyResults = 0;
$this->cycleCount = 0;
$this->startTime = 0;
$this->totalApiTime = 0;
$this->totalDownloadTime = 0;
$this->totalTransformTime = 0;
$this->totalProcessTime = 0;
$this->totalJournalFilesDownloaded = 0;
$this->totalEventsProcessed = 0;
$this->emptyJournalFiles = 0;
$this->otherPortalSkipped = 0;
}
public function hasStopFlag(): bool
{
return (bool) Redis::exists(self::STOP_FLAG_KEY);
}
/**
* Calculate adaptive sleep duration based on consecutive empty results
*/
private function calculateAdaptiveSleep(): int
{
if ($this->consecutiveEmptyResults < self::EMPTY_THRESHOLD_FOR_BACKOFF) {
return self::BASE_SLEEP_SECONDS; // 5 second
}
// Progressive backoff: 15s -> 30s -> 60s -> 120s (max)
$delay = 3 * self::BASE_SLEEP_SECONDS;
$sleepDuration = $delay * (2 ** ($this->consecutiveEmptyResults - self::EMPTY_THRESHOLD_FOR_BACKOFF));
return min($sleepDuration, self::MAX_SLEEP_SECONDS);
}
private function logPollingStart(): void
{
Log::info('[HubSpot Journal Polling] Service starting', [
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'initial_memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Log polling service end information
*/
private function logPollingEnd(): void
{
$runtime = time() - $this->startTime;
$cycles = max($this->cycleCount, 1);
Log::info('[HubSpot Journal Polling] Service ending', [
'runtime_seconds' => $runtime,
'total_cycles' => $this->cycleCount,
'files_downloaded' => $this->totalJournalFilesDownloaded,
'empty_files' => $this->emptyJournalFiles,
'other_portal_skipped' => $this->otherPortalSkipped,
'total_events' => $this->totalEventsProcessed,
'events_per_file' => $this->totalJournalFilesDownloaded > 0
? round($this->totalEventsProcessed / $this->totalJournalFilesDownloaded, 1)
: 0,
'avg_api_ms' => round($this->totalApiTime / $cycles, 1),
'avg_download_ms' => round($this->totalDownloadTime / $cycles, 1),
'avg_transform_ms' => round($this->totalTransformTime / $cycles, 1),
'avg_process_ms' => round($this->totalProcessTime / $cycles, 1),
'peak_memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
]);
}
/**
* Improved stop condition check with clear reasoning
*/
private function shouldContinuePolling(): bool
{
// Check explicit stop request first (fastest check)
if ($this->shouldStop()) {
Log::info('[HubSpot Journal Polling] Stop requested, ending polling');
return false;
}
if ($this->consecutiveEmptyResults >= self::MAX_EMPTY_RESULTS_BEFORE_EXIT) {
Log::warning('[HubSpot Journal Polling] Maximum empty results reached, stopping', [
'empty_results' => $this->consecutiveEmptyResults,
'max_empty_results' => self::MAX_EMPTY_RESULTS_BEFORE_EXIT,
]);
return false;
}
// Check runtime limit (4 minutes)
$runtime = time() - $this->startTime;
if ($runtime >= self::MAX_RUNTIME_SECONDS) {
Log::warning('[HubSpot Journal Polling] Maximum runtime reached, stopping', [
'runtime_seconds' => $runtime,
'runtime_minutes' => round($runtime / 60, 1),
'max_runtime_seconds' => self::MAX_RUNTIME_SECONDS,
]);
return false;
}
// Check memory limits (prevent OOM)
$currentMemory = memory_get_usage(true);
$memoryLimitBytes = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($memoryLimitBytes > 0 && $currentMemory > ($memoryLimitBytes * self::MEMORY_CRITICAL_THRESHOLD / 100)) {
Log::warning('[HubSpot Journal Polling] Memory limit approaching, stopping', [
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit' => ini_get('memory_limit'),
'usage_percent' => round(($currentMemory / $memoryLimitBytes) * 100, 1),
]);
return false;
}
// Check for excessive cycles (prevent runaway processes)
if ($this->cycleCount > self::MAX_CYCLES_DEFAULT) {
Log::warning('[HubSpot Journal Polling] Maximum cycles reached, stopping', [
'cycles' => $this->cycleCount,
'max_cycles' => self::MAX_CYCLES_DEFAULT,
]);
return false;
}
return true;
}
/**
* Handle when work is found - reset counters and continue immediately
*/
private function handleWorkFound(): void
{
$this->consecutiveEmptyResults = 0;
}
/**
* Handle when no work is found - implement adaptive sleep
*/
private function handleNoWorkFound(): void
{
$this->consecutiveEmptyResults++;
$sleepDuration = $this->calculateAdaptiveSleep();
Log::debug('[HubSpot Journal Polling] No work found, sleeping', [
'consecutive_empty' => $this->consecutiveEmptyResults,
'sleep_seconds' => $sleepDuration,
'cycle' => $this->cycleCount,
]);
$this->responsiveSleep($sleepDuration);
}
/**
* Sleep with responsive stop checking
*/
private function responsiveSleep(int $seconds): void
{
for ($i = 0; $i < $seconds && $this->shouldContinuePolling(); $i++) {
sleep(1);
}
}
/**
* Parse memory limit string to bytes
*/
private function parseMemoryLimit(string $memoryLimit): int
{
if ($memoryLimit === '-1') {
return 0; // Unlimited
}
$unit = strtolower(substr($memoryLimit, -1));
$value = (int) substr($memoryLimit, 0, -1);
return match ($unit) {
'g' => $value * 1024 * 1024 * 1024,
'm' => $value * 1024 * 1024,
'k' => $value * 1024,
default => (int) $memoryLimit,
};
}
private function executePollingCycle(): void
{
$this->renewLockIfNeeded();
$result = $this->pollOnce();
if ($result === true) {
$this->handleWorkFound();
} elseif ($result === false) {
$this->handleNoWorkFound();
}
}
private function renewLockIfNeeded(): void
{
$now = time();
if ($now - $this->lastLockRenewal >= self::LOCK_RENEWAL_INTERVAL) {
$this->renewPollingLock();
$this->lastLockRenewal = $now;
}
}
private function renewPollingLock(): void
{
$expiresAt = now()->addSeconds(self::LOCK_TTL_SECONDS)->toISOString();
$lockData = [
'locked' => true,
'expires_at' => $expiresAt,
'acquired_at' => now()->toISOString(),
'renewed_at' => now()->toISOString(),
'cycle' => $this->cycleCount,
];
Redis::setex(self::POLLING_LOCK_KEY, self::LOCK_TTL_SECONDS, json_encode($lockData));
Log::debug('[HubSpot Journal Polling] Lock renewed', [
'expires_at' => $expiresAt,
'cycle' => $this->cycleCount,
]);
}
private function handleApiResult(JournalApiResult $result, string $context): bool
{
if ($result->failureType === JournalApiResult::FAILURE_AUTH) {
Log::warning('[HubSpot Journal Polling] Auth failure, will retry next cycle', [
'context' => $context,
]);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_RATE_LIMIT) {
$waitSeconds = min($result->retryAfterSeconds ?? 60, self::MAX_BACKOFF_SECONDS);
Log::warning('[HubSpot Journal Polling] Rate limit hit, waiting', [
'wait_seconds' => $waitSeconds,
]);
$this->responsiveSleep($waitSeconds);
return false;
}
if ($result->failureType === JournalApiResult::FAILURE_OFFSET_EXPIRED) {
Log::warning('[HubSpot Journal Polling] Offset expired, resetting to fetch latest data', [
'expired_offset' => $context,
]);
$this->resetOffset();
$this->resetDbOffset();
return false;
}
if ($result->isPermanentFailure()) {
Log::error('[HubSpot Journal Polling] Permanent API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->shouldStop = true;
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable API failure', [
'context' => $context,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Clean up polling session resources
*/
private function cleanupPollingSession(): void
{
$this->logPollingEnd();
$this->storeOffsetInDB();
$this->releasePollingLock();
$this->apiClient->clearPortalCache();
$this->resetPollingState();
}
private function storeOffsetInDB(): void
{
// Save current offset to database before cleanup
$currentOffset = $this->getCurrentOffset(cacheOnly: true);
if ($currentOffset) {
$this->updateDbOffset($currentOffset);
Log::info('[HubSpot Journal Polling] Saved offset to database on cleanup', [
'offset' => $currentOffset,
]);
}
}
private function handleDownloadResult(JournalApiResult $result, string $offset, int $retryCount): ?bool
{
if ($result->failureType === JournalApiResult::FAILURE_UNKNOWN_PORTAL) {
$this->otherPortalSkipped++;
$this->updateOffset($offset);
return null;
}
if ($result->isPermanentFailure()) {
Log::warning('[HubSpot Journal Polling] Permanent failure, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'error' => $result->errorMessage,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::error('[HubSpot Journal Polling] Max retries reached, skipping offset', [
'offset' => $offset,
'portal_id' => $result->portalId,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
]);
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::warning('[HubSpot Journal Polling] Retryable failure, will retry', [
'offset' => $offset,
'failure_type' => $result->failureType,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
]);
$this->offsetRetryCount[$offset] = $retryCount;
if ($result->retryAfterSeconds) {
sleep(min($result->retryAfterSeconds, self::MAX_BACKOFF_SECONDS));
}
return false;
}
/**
* Handle transformation failure with retry logic
*/
private function handleTransformationFailure(string $offset, int $retryCount, \Exception $exception): bool
{
$retryCount++;
if ($retryCount >= self::MAX_OFFSET_RETRIES) {
Log::critical('[HubSpot Journal Polling] Max transformation retries reached - SKIPPING offset', [
'offset' => $offset,
'retry_count' => $retryCount,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Skip this offset to prevent infinite loop with corrupted data
$this->updateOffset($offset);
$this->clearOffsetRetryCount($offset);
return false;
}
Log::error('[HubSpot Journal Polling] Transformation failed - will retry', [
'offset' => $offset,
'retry_count' => $retryCount,
'max_retries' => self::MAX_OFFSET_RETRIES,
'error' => $exception->getMessage(),
]);
$this->offsetRetryCount[$offset] = $retryCount;
return false;
}
/**
* Clear retry count for an offset after successful processing
*/
private function clearOffsetRetryCount(string $offset): void
{
unset($this->offsetRetryCount[$offset]);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Sync Changes
Hide This Notification
Code changed:
Hide
45
1
41
66
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.own...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85307
|
2920
|
33
|
2026-05-28T12:17:43.017737+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970663017_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeRefactorRunToolsGi PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4‹$0(ah]БГ100% <78• Thu 28 May 15:17:42181ec2-user@ip-10-30-140-…₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
-2124905150863850945
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeRefactorRunToolsGi PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4‹$0(ah]БГ100% <78• Thu 28 May 15:17:42181ec2-user@ip-10-30-140-…₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85306
|
NULL
|
NULL
|
NULL
|
|
85308
|
2921
|
33
|
2026-05-28T12:17:42.906769+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970662906_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotJournalPollingService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
SluCkVIChRotonWindowHelpPwovscors#12121 on JY-2096 SluCkVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice pn.ne beloers.ohtpelereobiecistraicon© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phpCyActwwooserver.pnp© ContactObserver.phpGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhome CopperimermobiacteNacorateA ctivinDummym Helnarsv im Hibsod(i) AccountSyncStrategIhctiontD ContactSyncStrateay› DDTO› DFieldswn taueeaOLeAkоkyscrco.onO UserSHStoy-prpTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances.3073esepolsinalocko: bool›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisition88Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.$ 3329331333PolLinglock@= woidtC UTHAAAARAAAA@ HubspotDeaMohhonie 346(C) Hubspot.JournalApiClie© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho© JournalBatchSizelimitElling lock (for emergency situations)› LeaseLock(): voidf...}C) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteSamiceTesuphr©ActivityControlier.php© Team.phpe Kecneupnis=custom.logtraveuoeA console [STAGING— 78%786707708709710712-74717-218728)724733AND a.created at> DATSoGROUP BY u.id, u.email,ORDER BY sne count DESMJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM activitioSELECT * FROM actávitioSELECT * FROM crn configSELECT # FROM teans WHERselleetron usens whenselect + fron plavbookeseleetron miawhonkeselect * fron playbook_cseleet ron eoeselect + fron eon Sieldselect * fron activitys7o0sLXinu co woy to.l/.HoeJiminny ... -# buescontusion-dinig@ Describe what you are looking for* €. Vasil Vasileve MessagerAdd canvasfiles.за третата точка обаче наистина ли няма подържкаDooyw00sie the neoole of fimillEontt Verhint1 Stelivan Georsie.D Vod&r MireNikolav Vanko&o James GrahamLukas Kovalky...
|
NULL
|
4682376769155574518
|
NULL
|
click
|
ocr
|
NULL
|
SluCkVIChRotonWindowHelpPwovscors#12121 on JY-2096 SluCkVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice pn.ne beloers.ohtpelereobiecistraicon© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phpCyActwwooserver.pnp© ContactObserver.phpGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhome CopperimermobiacteNacorateA ctivinDummym Helnarsv im Hibsod(i) AccountSyncStrategIhctiontD ContactSyncStrateay› DDTO› DFieldswn taueeaOLeAkоkyscrco.onO UserSHStoy-prpTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances.3073esepolsinalocko: bool›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisition88Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.$ 3329331333PolLinglock@= woidtC UTHAAAARAAAA@ HubspotDeaMohhonie 346(C) Hubspot.JournalApiClie© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho© JournalBatchSizelimitElling lock (for emergency situations)› LeaseLock(): voidf...}C) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteSamiceTesuphr©ActivityControlier.php© Team.phpe Kecneupnis=custom.logtraveuoeA console [STAGING— 78%786707708709710712-74717-218728)724733AND a.created at> DATSoGROUP BY u.id, u.email,ORDER BY sne count DESMJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM activitioSELECT * FROM actávitioSELECT * FROM crn configSELECT # FROM teans WHERselleetron usens whenselect + fron plavbookeseleetron miawhonkeselect * fron playbook_cseleet ron eoeselect + fron eon Sieldselect * fron activitys7o0sLXinu co woy to.l/.HoeJiminny ... -# buescontusion-dinig@ Describe what you are looking for* €. Vasil Vasileve MessagerAdd canvasfiles.за третата точка обаче наистина ли няма подържкаDooyw00sie the neoole of fimillEontt Verhint1 Stelivan Georsie.D Vod&r MireNikolav Vanko&o James GrahamLukas Kovalky...
|
85305
|
NULL
|
NULL
|
NULL
|
|
85306
|
2920
|
32
|
2026-05-28T12:17:16.355344+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970636355_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"on_screen":true,"role_description":"text"}]...
|
5885083440351273838
|
-5801313977300174098
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4‹$0(ah]БГ100% <78• Thu 28 May 15:17:15181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85305
|
2921
|
32
|
2026-05-28T12:17:16.246769+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970636246_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.54488033,"top":0.1867518,"width":0.022938829,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.016289894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54488033,"top":0.20909816,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54521275,"top":0.23144454,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.041888297,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":19,"bounds":{"left":0.54355055,"top":0.25379092,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.27613726,"width":0.02825798,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.040226065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":17,"bounds":{"left":0.54355055,"top":0.29848364,"width":0.038896278,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.029920213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.32083002,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.023271276,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54355055,"top":0.34317636,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.03158245,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.36552274,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.38786912,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.4102155,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.54421544,"top":0.43256184,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.54421544,"top":0.45490822,"width":0.016289894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.017287234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54454786,"top":0.4772546,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.024601065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.49960095,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.045212764,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.54421544,"top":0.5219473,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.5746209,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.037898935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54488033,"top":0.5969673,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.03324468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54355055,"top":0.61931366,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.030917553,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54488033,"top":0.64166003,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54521275,"top":0.6640064,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.03523936,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.6863527,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54454786,"top":0.7086991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.54488033,"top":0.7310455,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.007978723,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.54521275,"top":0.75339186,"width":0.004986702,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.010305851,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.004654255,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.546875,"top":0.77573824,"width":0.005319149,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.032912236,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.5462101,"top":0.7980846,"width":0.028922873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"bounds":{"left":0.5422208,"top":0.820431,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.820431,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54421544,"top":0.820431,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54488033,"top":0.8427773,"width":0.026928192,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0063164895,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.5767952,"top":0.8427773,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.021941489,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.8954509,"width":0.019946808,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.011635638,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.54454786,"top":0.91779727,"width":0.00930851,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.5422208,"top":0.94014364,"width":0.030585106,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.94014364,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.94014364,"width":0.032912236,"height":0.014365523}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":9,"bounds":{"left":0.60206115,"top":0.09177973,"width":0.030917553,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":11,"bounds":{"left":0.61136967,"top":0.10055866,"width":0.018949468,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.61136967,"top":0.10055866,"width":0.0039893617,"height":0.012769354}},{"char_start":1,"char_count":7,"bounds":{"left":0.61535907,"top":0.10055866,"width":0.014960106,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":10,"bounds":{"left":0.63397604,"top":0.09177973,"width":0.034242023,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":12,"bounds":{"left":0.64328456,"top":0.10055866,"width":0.022273935,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.64328456,"top":0.10055866,"width":0.0033244682,"height":0.012769354}},{"char_start":1,"char_count":9,"bounds":{"left":0.6462766,"top":0.10055866,"width":0.019281914,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":9,"bounds":{"left":0.66921544,"top":0.09177973,"width":0.020944148,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":11,"bounds":{"left":0.67852396,"top":0.10055866,"width":0.008976064,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Pins","depth":9,"bounds":{"left":0.69148934,"top":0.09177973,"width":0.020279255,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Pins","depth":11,"bounds":{"left":0.70079786,"top":0.10055866,"width":0.00831117,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":9,"bounds":{"left":0.71276593,"top":0.09177973,"width":0.010970744,"height":0.030327214},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.015957447,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.007978723,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.013962766,"height":0.0007980846},"on_screen":true,"role_description":"text"}]...
|
6751715278102888471
|
-1190718399862564146
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-Proinet vecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.logtraveuoe© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phpGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhome CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLenkоkyseiwico.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeorcolmererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esePolLingLock: bool700-78— 78%783704705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hoth oek nndl aynsnatondntCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88733712=213N726715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA73@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}737739© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sne count DESKselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans t 1.n<->1: onWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_cselleet ron eoselselect * fron crn_field.SELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity 3d= 70073ANn & con nrovsden 3aSELECT * FROM activitymselect * fron users whenPARAtT GAAR MANGUREANOohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# hapoy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-be# platform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7inu co woy to.l/.l@ Describe what you are looking for* €. Vasil Vasileve Messageru Add canvasu riiesLukas Kovalik 3.07 PMок, аз го пуснах пак през geminза третата точка обаче наистина ли няма подьржкаДаз май си ги ползвам някьлеили е друг driverVasil Vasilev 3:10 PMне става, оях го направил така, и се счуткLukas Kovalik 3-10 PMaMиnor men euywiidVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. 'nx' = true. ex =60)c phpredis не ставаlmkas Kovallk 2a11ptтака май не работеше Sresult - Redis:set(StestKey, StestValue, "EX, Stti, "NX"); а така да Sresult - Redis:set(StestKey, StestValue, (nx, 'ex' => Stti)):WcllvaGleu 210Vвторото пробвах, и не станаLukas Kovalik 3.12 pNмnh оbлaтноне помня ROUIVasil Vasilev 3:12 PMовратното може ла еLukas Kovalik 3:12 PMможе и ла брькамVasil Vasilev 3:12 PMв кода имаSlockAcquired = Rediss:set(self::POLLING_LOCKLKEY, ison_encode(SlockDota). "EX". self::LOCK TTILSECONDS. *NX*)Ausun as nhard naboruда и в aрр/Services/Crm/Hubspot/Client.php:10:we ro onnapgLukas Kovalik 316 PMShift + Return to aid a now in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85304
|
2921
|
31
|
2026-05-28T12:17:11.494144+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970631494_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"}]...
|
6801348342327917455
|
-5774503434061136129
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.logtraveuoe© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phpGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorateA ctivinDummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO› DFieldswn taueeaOLenkоkyseiwico.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeorcolmererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool700-78— 78%783704705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hoth oek nndl aynsnatondntCoyns noeht> now()->toIS0String(317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88733712=213N726715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexoinesAt.722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA73@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielling lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}737739© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sne count DESKselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans t 1.n<->1: onWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_cselleet ron eoselselect * fron crn_field.SELECT * FROM crn_field_JOTM eon Belds + 0M€n• JOIN activities a ON €NHERF Actwity 3d = 70073AND € con onoviden saSELECT * FROM activitymselect * fron users whenPARAtT GAAR MANGUREANOohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-be# platform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamator1 Stelivan Georsie.D Vod&r MireNikolav Vanko¿. James GrahamLukas KovalkyTO0% L7Inu co woy to./el@ Describe what you are looking for* €. Vasil Vasileve Messageru Add canvasu riiesLukas Kovalik 3.07 PMок, аз го пуснах пак през geminза третата точка обаче наистина ли няма подьржкаДаз май си ги ползвам някьлеили е друг driverVasil Vasilev 3:10 PMне става, оях го направил така, и се счуткLukas Kovalik 3-10 PMaMиnor men euywiidVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. 'nx' = true. ex =60)c phpredis не ставаlmkas Kovallk 2a11ptтака май не работеше Sresult - Redis:set(StestKey, StestValue, "EX, Stti, "NX"); а така да Sresult - Redis:set(StestKey, StestValue, (nx, 'ex' => Stti)):WcllvaGleu 210Vвторото пробвах, и не станаLukas Kovalik 3.12 pNмnh оbлaтноне помня ROUIVasil Vasilev 3:12 PMовратното може ла еLukas Kovalik 3:12 PMможе и ла брькамVasil Vasilev 3:12 PMв кода имаSlockAcquired = Rediss:set(self::POLLING_LOCK.KEY, ison_encode(SlockDota)EXsertiKTsEoNsNAusun as nhard naboruда и в apр/Services/Crm/Hubspot/Client.php:10we ro onnapgLukas Kovalik 316 PMShift + Return to aid a now in...
|
85302
|
NULL
|
NULL
|
NULL
|
|
85303
|
2920
|
31
|
2026-05-28T12:17:08.440370+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970628440_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"}]...
|
-9164664127350781039
|
-8080490479297806593
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"X4(ah]БГ100% <78• Thu 28 May 15:17:08181ec2-user@ip-10-30-140-...₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85301
|
NULL
|
NULL
|
NULL
|
|
85302
|
2921
|
30
|
2026-05-28T12:17:08.341713+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970628341_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"}]...
|
-2425159673066298448
|
-5783511732823048449
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-Proinet vecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.logtraveuoe© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phpGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhome CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO› DFieldswn taueeaOLenkоkyseiwico.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeorcolmererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool700-78— 78%783704705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hoth oek nndl aynsnatondntCoyns noeht> now()->toIS0String(317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88733712=213N726715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA73@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}737739© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sne count DESKselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans t 1.n<->1: onWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_cselleet ron eoselselect * fron crn_field.SELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity 3d= 70073ANn & con nrovsden 3aSELECT * FROM activitymselect * fron users whenPARAtT GAAR MANGUREANOohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# hapoy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-be# platform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7inu co woy to.ly@ Describe what you are looking for* €. Vasil Vasileve Messageru Add canvasu riiesLukas Kovalik 3.07 PMок, аз го пуснах пак през geminза третата точка обаче наистина ли няма подьржкаДаз май си ги ползвам някьлеили е друг driverVasil Vasilev 3:10 PMне става, оях го направил така, и се счуткLukas Kovalik 3-10 PMaMиnor men euywiidVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. 'nx' = true. ex =60)c phpredis не ставаlmkas Kovallk 2a11ptтака май не работеше Sresult - Rediseset(StestKey, StestValue, "EX, Sttl, "NX"); а така да Sresult - Redis::set(StestKey, StestValue, (nx, 'ex" => Sttl)):WcllvaGleu 210Vвторото пробвах, и не станаLukas Kovalik 3.12 pNмnh оbлaтноне помня ROUIVasil Vasilev 3:12 PMовратното може ла еLukas Kovalik 3:12 PMможе и ла брькамVasil Vasilev 3:12 PMв кода имаSlockAcquired = Rediss:set(self::POLLING_LOCKLKEY, ison_encode(SlockDota). "EX". self::LOCK TTILSECONDS. *NX*)Ausun as nhard naboruда и в aрр/Services/Crm/Hubspot/Client.php:10:we ro onnapgLukas Kovalik 316 PMShift + Return to aid a now in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85301
|
2920
|
30
|
2026-05-28T12:17:05.182221+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970625182_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Vasil Vasilev
Today at 1:23:53 PM
1:23 PM
като имаш време, разгледай този интересен ПР:
https://github.com/jiminny/app/pull/12130
https://github.com/jiminny/app/pull/12130
Today at 1:25:05 PM
1:25
написах supervisor клас AsyncUpdateSupervisor, който се пали от supervisorctl, като тоя клас AsyncUpdateSupervisor пуска два паралелни процеса, един за обработка на активита и втори за обработка на сделки
Today at 1:25:47 PM
1:25...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.56805557,"top":0.0,"width":0.06388889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.56805557,"top":0.0,"width":0.007638889,"height":0.02}},{"char_start":1,"char_count":14,"bounds":{"left":0.57569444,"top":0.0,"width":0.06875,"height":0.02}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":10,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":12,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Pins","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Pins","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":9,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":15,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Vasil Vasilev","depth":16,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 1:23:53 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:23 PM","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"като имаш време, разгледай този интересен ПР:","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"https://github.com/jiminny/app/pull/12130","depth":17,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"https://github.com/jiminny/app/pull/12130","depth":18,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 1:25:05 PM","depth":17,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:25","depth":18,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"написах supervisor клас AsyncUpdateSupervisor, който се пали от supervisorctl, като тоя клас AsyncUpdateSupervisor пуска два паралелни процеса, един за обработка на активита и втори за обработка на сделки","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 1:25:47 PM","depth":17,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:25","depth":18,"on_screen":false,"role_description":"text"}]...
|
-2013527072008241433
|
-8279102772793600242
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Vasil Vasilev
Today at 1:23:53 PM
1:23 PM
като имаш време, разгледай този интересен ПР:
https://github.com/jiminny/app/pull/12130
https://github.com/jiminny/app/pull/12130
Today at 1:25:05 PM
1:25
написах supervisor клас AsyncUpdateSupervisor, който се пали от supervisorctl, като тоя клас AsyncUpdateSupervisor пуска два паралелни процеса, един за обработка на активита и втори за обработка на сделки
Today at 1:25:47 PM
1:25
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"‹$0(ah]БГ100% <78• Thu 28 May 15:17:05181ec2-user@ip-10-30-140-...₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85300
|
2921
|
29
|
2026-05-28T12:17:03.786296+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970623786_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.54488033,"top":0.1867518,"width":0.022938829,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.016289894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54488033,"top":0.20909816,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54521275,"top":0.23144454,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.041888297,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":19,"bounds":{"left":0.54355055,"top":0.25379092,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.27613726,"width":0.02825798,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.040226065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":17,"bounds":{"left":0.54355055,"top":0.29848364,"width":0.038896278,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.029920213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.32083002,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.023271276,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54355055,"top":0.34317636,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.03158245,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.36552274,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.38786912,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.4102155,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.54421544,"top":0.43256184,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.54421544,"top":0.45490822,"width":0.016289894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.017287234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54454786,"top":0.4772546,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.024601065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.49960095,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.045212764,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.54421544,"top":0.5219473,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.5746209,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.037898935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54488033,"top":0.5969673,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.03324468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54355055,"top":0.61931366,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.030917553,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54488033,"top":0.64166003,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54521275,"top":0.6640064,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.03523936,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.6863527,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54454786,"top":0.7086991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.54488033,"top":0.7310455,"width":0.03557181,"height":0.014365523}}],"role_description":"text"}]...
|
1282717916426910583
|
-5801313977132400914
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-Proinet vecanyice ph.ne beloers.ohtnelereooiecistraicon:SamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityaireoonM AvatalTeallendara Bullhome CopperimermobiacteNacorateA ctivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLenkоkyseiwico.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeorcolmererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosco ourhalroto noservana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78378705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0String(711712=213N 224715317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.[PHONE]23$ 3725329331333732PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielling lock (for emergency situations)© Hubspot.JournalPolling! 348737@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans t 1.n<->1: onWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect + fron olavbookselleet ron eoselselect * fron crn_field.SELECT * FROM crn_field_JOTM eon Belds + 0M€n• JOIN activities a ON €NHERF Actwity 3d = 70073ANn & eon nrovsden 3alSELECT * FROM activitymselect * fron users whenPARAtT GAAR MANGUREANOohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysHoeDMsActivity00LateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# general# hapoy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-be# platform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamTO0% L7inu co woy to.ly.us@ Describe what you are looking forVasil Vasileve MessagerAdd canvas© Files & Pins +tntanhonsTodan3 сьщо e intentional поради факта, че phpredis driver-a не поддьржа set ex +nх параметри, и трябва да се пуснат две операции set + expireLukas Kovalik 3:07PMок, аз го пуснах пак през geminза третата точка обаче наистина ли няма подьржкаваз май си ги ползвам някьлеили е друг driverVasil Vasiley 3-10 PMHcan oix to hanoabntak"cwwnLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set Skey. Svalue. inx' = true, ex =60)c nhnredis нe crapaltkac Kow.ik 2401така май не работеше Sresult = Redis:set(StestKey, StestValue, "EX, Sttl, "NX); а така да Sresult = Redis:set(StestKey, StestValue, inx, ex => Sttl):Vasil Vasiley 314 pvвторото пробвах, и не станаLukas Kovalik 3412 ptне помня вечеVasil Vasilev 3:12 PMоооатноо можел%еLukas Kovalik 3:12 PMможе и да брькамVasil Vasilev 3.12 PMв кола имаSlockAcquired = Redis::set(self::POLLING_LOCKLKEY, ison_encode(SlockDato). "EX" self::LOCK_TTLSECONDS)Ausul aineatd nahotuда и в aрр/Services/Crm/Hubspot/Client.php:10Vasil Vasilev 3.14PM...
|
85298
|
NULL
|
NULL
|
NULL
|
|
85299
|
2920
|
29
|
2026-05-28T12:17:02.392970+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970622392_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"}]...
|
-2917331277012372565
|
-5815000689293182809
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"X4‹$0(ah]БГ100% <78• Thu 28 May 15:17:02181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85297
|
NULL
|
NULL
|
NULL
|
|
85298
|
2921
|
28
|
2026-05-28T12:17:01.170755+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970621170_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"}]...
|
-3883925369523364552
|
-8120950368302055689
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtnelereooiecistraicon:SamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityaireoonM Avatallealendara Bullhomleosee CopperimermobiacteNacorateA ctivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLenkоkyseiwico.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeorcolmererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosco ourhalroto noservana lock to orevent auloole instances3073esePolLingLock: bool— 78%78378705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0String(317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88711712=213N 724715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.[PHONE]23$ 3725329331333732PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielling lock (for emergency situations)© Hubspot.JournalPolling! 348737@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans t 1.n<->1: onWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect + fron olavbookselleet ron eoselselect * fron crn_field.SELECT * FROM crn_field_JOTM eon Belds + 0M€n• JOIN activities a ON €NHERF Actwity 3d = 70073ANn & eon nrovsden 3alSELECT * FROM activitymselect * fron users whenPARAtT GAAR MANGUREANOohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysHoeDMsActivity00LateMonJiminnY …# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-be# platform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamator1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamTO0% L7Inu co moy to.y.ul@ Describe what you are looking forVasil Vasileve MessagerAdd canvas© Files & Pins +tntanhonsTodar3 сьщо e intentional поради факта, че phpredis driver-a не поддьржа set ex +nх параметри, и трябва да се пуснат две операции set + expireLukas Kovalik 3:07PMок, аз го пуснах пак през geminза третата точка обаче наистина ли няма подьржкаваз май си ги ползвам някьлеили е друг driverVasil Vasiley 3-10 PMHcan oix to hanoabntak"cwwnLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set Skey. Svalue. inx' = true, ex =60)c nhnredis нe crapaltkac Kow.ik 2401така май не работеше Sresult = Redis:set(StestKey, StestValue, "EX, Sttl, "NX); а така да Sresult = Redis:set(StestKey, StestValue, inx, ex => Sttl):Vasil Vasiley 314 pvвторото пробвах, и не станаLukas Kovalik 3412 ptне помня вечеVasil Vasilev 3:12 PMоооатноо можел%еLukas Kovalik 3:12 PMможе и да брькамVasil Vasilev 3.12 PMв кола имаSlockAcquired = Redis::set(self::POLLING_LOCKLKEY, ison_encode(SlockDato). "EX" self::LOCK_TTLSECONDS)Ausul aineatd nahotuLukas Kovalik 3:13 PMда и в aрр/Services/Crm/Hubspot/Client.php:10Vasil Vasilev 3.14PMShift + Return to aid a now in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85297
|
2920
|
28
|
2026-05-28T12:17:01.027659+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970621027_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"on_screen":true,"role_description":"text"}]...
|
2106422949835709697
|
-5801313968542466322
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4(ah]БГ100% <78• Thu 28 May 15:17:00181ec2-user@ip-10-30-140-...₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85296
|
2921
|
27
|
2026-05-28T12:16:56.251402+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970616251_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-2096 SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringOf Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu co moy 1o:l0.o@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
NULL
|
6977492559102109624
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-2096 SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringOf Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu co moy 1o:l0.o@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
85294
|
NULL
|
NULL
|
NULL
|
|
85295
|
2920
|
27
|
2026-05-28T12:16:54.400537+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970614400_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 12:00:37 PM
12:00
малко по късно и на мен ще ми трябва ревю за един голям feature
Today at 12:00:46 PM
12:00
но ще ти пиша, като е готов за гледане
(edited)
Lukas Kovalik
Today at 12:11:37 PM
12:11 PM
ок , mersi
Vasil Vasilev...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.56805557,"top":0.0,"width":0.06388889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.56805557,"top":0.0,"width":0.007638889,"height":0.02}},{"char_start":1,"char_count":14,"bounds":{"left":0.57569444,"top":0.0,"width":0.06875,"height":0.02}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":10,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":12,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Pins","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Pins","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":9,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":14,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:00:37 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:00","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"малко по късно и на мен ще ми трябва ревю за един голям feature","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 12:00:46 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:00","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"но ще ти пиша, като е готов за гледане","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":15,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 12:11:37 PM","depth":15,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11 PM","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ок , mersi","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Vasil Vasilev","depth":15,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5932853540874746653
|
-8684150722586768566
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 12:00:37 PM
12:00
малко по късно и на мен ще ми трябва ревю за един голям feature
Today at 12:00:46 PM
12:00
но ще ти пиша, като е готов за гледане
(edited)
Lukas Kovalik
Today at 12:11:37 PM
12:11 PM
ок , mersi
Vasil Vasilev
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"‹$0(ah]БГ100% <78• Thu 28 May 15:16:53181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85293
|
NULL
|
NULL
|
NULL
|
|
85294
|
2921
|
26
|
2026-05-28T12:16:54.298610+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970614298_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.54488033,"top":0.1867518,"width":0.022938829,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.016289894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54488033,"top":0.20909816,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54521275,"top":0.23144454,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.041888297,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":19,"bounds":{"left":0.54355055,"top":0.25379092,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.27613726,"width":0.02825798,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.040226065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":17,"bounds":{"left":0.54355055,"top":0.29848364,"width":0.038896278,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.029920213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.32083002,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.023271276,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54355055,"top":0.34317636,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.03158245,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.36552274,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.38786912,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.4102155,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.54421544,"top":0.43256184,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.54421544,"top":0.45490822,"width":0.016289894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.017287234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54454786,"top":0.4772546,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.024601065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.49960095,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.045212764,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.54421544,"top":0.5219473,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.5746209,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.037898935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54488033,"top":0.5969673,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.03324468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54355055,"top":0.61931366,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.030917553,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54488033,"top":0.64166003,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54521275,"top":0.6640064,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.03523936,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.6863527,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54454786,"top":0.7086991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.54488033,"top":0.7310455,"width":0.03557181,"height":0.014365523}}],"role_description":"text"}]...
|
1282717916426910583
|
-5801313977132400914
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringOf Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu co moy to:loros@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85293
|
2920
|
26
|
2026-05-28T12:16:52.069057+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970612069_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"}]...
|
3710432402713954634
|
-5812785164765151489
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"84‹$0(ah]БГ100% <78• Thu 28 May 15:16:51181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85292
|
2921
|
25
|
2026-05-28T12:16:49.945700+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970609945_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-2096 SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO› DFieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu cowoy 1o:10.4@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
NULL
|
-1266567188414427442
|
NULL
|
typing_pause
|
ocr
|
NULL
|
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-2096 SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO› DFieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu cowoy 1o:10.4@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
85290
|
NULL
|
NULL
|
NULL
|
|
85291
|
2920
|
25
|
2026-05-28T12:16:47.677386+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970607677_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"}]...
|
-177824806450888117
|
-8136785577719153025
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"€ 84‹$0(ah]БГ100% <78• Thu 28 May 15:16:47181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85289
|
NULL
|
NULL
|
NULL
|
|
85290
|
2921
|
24
|
2026-05-28T12:16:47.573254+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970607573_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.54488033,"top":0.1867518,"width":0.022938829,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.016289894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54488033,"top":0.20909816,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54521275,"top":0.23144454,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.041888297,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":19,"bounds":{"left":0.54355055,"top":0.25379092,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.27613726,"width":0.02825798,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.040226065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":17,"bounds":{"left":0.54355055,"top":0.29848364,"width":0.038896278,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.029920213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.32083002,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.023271276,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54355055,"top":0.34317636,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.03158245,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.36552274,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.38786912,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.4102155,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.54421544,"top":0.43256184,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.54421544,"top":0.45490822,"width":0.016289894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.017287234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54454786,"top":0.4772546,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.024601065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.49960095,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.045212764,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.54421544,"top":0.5219473,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.5746209,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.037898935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54488033,"top":0.5969673,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.03324468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54355055,"top":0.61931366,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.030917553,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54488033,"top":0.64166003,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54521275,"top":0.6640064,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.03523936,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.6863527,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54454786,"top":0.7086991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.54488033,"top":0.7310455,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.007978723,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.54521275,"top":0.75339186,"width":0.004986702,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.010305851,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.004654255,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.546875,"top":0.77573824,"width":0.005319149,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.032912236,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.5462101,"top":0.7980846,"width":0.028922873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"bounds":{"left":0.5422208,"top":0.820431,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.820431,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54421544,"top":0.820431,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54488033,"top":0.8427773,"width":0.026928192,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0063164895,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.5767952,"top":0.8427773,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.021941489,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.8954509,"width":0.019946808,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.011635638,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.54454786,"top":0.91779727,"width":0.00930851,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.5422208,"top":0.94014364,"width":0.030585106,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.94014364,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.94014364,"width":0.032912236,"height":0.014365523}}],"role_description":"text"}]...
|
-4580324126807770864
|
-5802371707351885078
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringOf Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7inu cowoy 1o.lo.@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85289
|
2920
|
24
|
2026-05-28T12:16:44.421580+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970604421_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeRefactorRunToolsGi PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4‹$0(ah]A100% <78• Thu 28 May 15:16:43181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
-6204676837341193982
|
NULL
|
typing_pause
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeRefactorRunToolsGi PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4‹$0(ah]A100% <78• Thu 28 May 15:16:43181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85288
|
2921
|
23
|
2026-05-28T12:16:43.381163+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970603381_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"}]...
|
-2425159673066298448
|
-5783511732823048449
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhome CopperimermobiacteNacorate A chivinDummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringOf Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas Kovalkyo0sLXInu cowoy to.lo.@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
85285
|
NULL
|
NULL
|
NULL
|
|
85287
|
2920
|
23
|
2026-05-28T12:16:43.279242+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970603279_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"}]...
|
3710432402713954634
|
-5812785164765151489
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4‹$0(ah]100% <478• Thu 28 May 15:16:42181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85286
|
NULL
|
NULL
|
NULL
|
|
85286
|
2920
|
22
|
2026-05-28T12:16:39.415255+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970599415_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"on_screen":true,"role_description":"text"}]...
|
1282717916426910583
|
-5801313977132400914
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"‹$0(ah]A100% <78• Thu 28 May 15:16:38181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85285
|
2921
|
22
|
2026-05-28T12:16:39.303349+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970599303_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.54488033,"top":0.1867518,"width":0.022938829,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.016289894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54488033,"top":0.20909816,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54521275,"top":0.23144454,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.041888297,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":19,"bounds":{"left":0.54355055,"top":0.25379092,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.27613726,"width":0.02825798,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.040226065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":17,"bounds":{"left":0.54355055,"top":0.29848364,"width":0.038896278,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.029920213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.32083002,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.023271276,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54355055,"top":0.34317636,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.03158245,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.36552274,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.38786912,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.4102155,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.54421544,"top":0.43256184,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.54421544,"top":0.45490822,"width":0.016289894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.017287234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54454786,"top":0.4772546,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.024601065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.49960095,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.045212764,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.54421544,"top":0.5219473,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.5746209,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.037898935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54488033,"top":0.5969673,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.03324468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54355055,"top":0.61931366,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.030917553,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54488033,"top":0.64166003,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54521275,"top":0.6640064,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.03523936,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.6863527,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54454786,"top":0.7086991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.54488033,"top":0.7310455,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.007978723,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.54521275,"top":0.75339186,"width":0.004986702,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.010305851,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.004654255,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.546875,"top":0.77573824,"width":0.005319149,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.032912236,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.5462101,"top":0.7980846,"width":0.028922873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"bounds":{"left":0.5422208,"top":0.820431,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.820431,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54421544,"top":0.820431,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54488033,"top":0.8427773,"width":0.026928192,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0063164895,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.5767952,"top":0.8427773,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.021941489,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.8954509,"width":0.019946808,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.011635638,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.54454786,"top":0.91779727,"width":0.00930851,"height":0.014365523}}],"role_description":"text"}]...
|
-1344434917273675558
|
-5802376096808494354
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhome CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO› DFieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas Kovalkyo0sLXInu comoy 1o:10.0e@ Describe what you are looking forVasil Vasileve MessagerNoRdd canv7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85284
|
2920
|
21
|
2026-05-28T12:16:36.451415+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970596451_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"}]...
|
-9164664127350781039
|
-8080490479297806593
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"- 884‹$0(ah]100% <78• Thu 28 May 15:16:35181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85281
|
NULL
|
NULL
|
NULL
|
|
85283
|
2921
|
21
|
2026-05-28T12:16:35.723725+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970595723_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"}]...
|
6801348342327917455
|
-5774503434061136129
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-Proinet vecanyice ph.ne beloers.ohtnelereooiecistraicon:SamiceTesuphr©ActivityControlier.php=custom.loglaravel.logJiminnY ….© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendarOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeorcolmererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786select + Eron teans wherlDMsselect + Eron coles.Activity# backend# buescontusion-dinig# donut_time#enpineerine# general# hapoy birthdavA infocoe intemal all›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:CEIEOTEBEan theat hothtoek ann ayns.matsondt711Coyns noeht> now()->toIS0String(712=213-74317318715f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88717-218Renewal = tineo,a Bullhom728)100: "[HubSpot Journal Polbingl Acquired polting lock".[e Copper• => SexojinesAt.722imermobiacte723Nacorate A chivin>@ Dummym Helnars$ 3v im Hibsod329(i) AccountSyncStrategMAetione331t ContactSyncStrateay› DDTO333> Ea Fieldswn taueeaPolLinglock@= woidtC UTHAAAARAAAA@ HubspotDeaMohhonie 34673733734735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natiooCONCATU.Id, CASE WH# infra-chansed# infrastructure desa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect + fron olavbookselleet ron eoselselect * fron crn_field.Late#bu-team-infoiliminny-best olatform-teamMon# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka StoyanovaSELECT * FROM crn_field_1a llivana NetsevaAOTM con Brelds 4 0M 4A Ctovan Tomnul• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron activitiesselect * fron users whenPARAtT GAAR MANGUREANOPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas Kovalkyout copied to clibboard• Stop@: void(...}ii:Appsselect * fron teans wherG tia Gloudselect * fron activitysselect * fron activitysM sanicetraiteTO0%7AInu comoy 1o:10.0e@ Describe what you are looking forVasil Vasileve MessagerNoRdd canvfiles.+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)Cnhnranic He caRaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMnau e ann/Services/Grm/Hubsnot/Glient oho:101Vasil Vasiley 314 pvwe to ononnsShift + Return to aid a now in...
|
85282
|
NULL
|
NULL
|
NULL
|
|
85282
|
2921
|
20
|
2026-05-28T12:16:30.935936+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970590935_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.54488033,"top":0.1867518,"width":0.022938829,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.016289894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54488033,"top":0.20909816,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54521275,"top":0.23144454,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.041888297,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":19,"bounds":{"left":0.54355055,"top":0.25379092,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.27613726,"width":0.02825798,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.040226065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":17,"bounds":{"left":0.54355055,"top":0.29848364,"width":0.038896278,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.029920213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.32083002,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.023271276,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54355055,"top":0.34317636,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.03158245,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.36552274,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.38786912,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.4102155,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.54421544,"top":0.43256184,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.54421544,"top":0.45490822,"width":0.016289894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.017287234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54454786,"top":0.4772546,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.024601065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.49960095,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.045212764,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.54421544,"top":0.5219473,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.5746209,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.037898935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54488033,"top":0.5969673,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.03324468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54355055,"top":0.61931366,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.030917553,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54488033,"top":0.64166003,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54521275,"top":0.6640064,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.03523936,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.6863527,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54454786,"top":0.7086991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.54488033,"top":0.7310455,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.007978723,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.54521275,"top":0.75339186,"width":0.004986702,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.010305851,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.004654255,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.546875,"top":0.77573824,"width":0.005319149,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.032912236,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.5462101,"top":0.7980846,"width":0.028922873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"bounds":{"left":0.5422208,"top":0.820431,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.820431,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54421544,"top":0.820431,"width":0.029920213,"height":0.014365523}}],"role_description":"text"}]...
|
7612895463447426448
|
-5801247997878355346
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu cowoy 1o:lo.sl@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85281
|
2920
|
20
|
2026-05-28T12:16:30.808826+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970590808_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.56805557,"top":0.0,"width":0.06388889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.56805557,"top":0.0,"width":0.007638889,"height":0.02}},{"char_start":1,"char_count":14,"bounds":{"left":0.57569444,"top":0.0,"width":0.06875,"height":0.02}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false}]...
|
-4338738367703541517
|
-5802442076096226582
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4‹$0(ah]БГ100% <78• Thu 28 May 15:16:30181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85280
|
2921
|
19
|
2026-05-28T12:16:21.722260+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970581722_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7221609583870463791
|
-8138701388860278221
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringOf Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7inu co moy to.loi@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
85278
|
NULL
|
NULL
|
NULL
|
|
85279
|
2920
|
19
|
2026-05-28T12:16:20.650702+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970580650_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"}]...
|
6106892229384445057
|
-5767818128486351105
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"₴4‹$0(ah]БГ100% <78• Thu 28 May 15:16:20181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85277
|
NULL
|
NULL
|
NULL
|
|
85278
|
2921
|
18
|
2026-05-28T12:16:19.430349+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970579430_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 12:00:37 PM
12:00
малко по късно и на мен ще ми трябва ревю за един голям feature
Today at 12:00:46 PM
12:00
но ще ти пиша, като е готов за гледане
(edited)
Lukas Kovalik
Today at 12:11:37 PM
12:11 PM
ок , mersi
Vasil Vasilev
Today at 1:23:53 PM
1:23 PM
като имаш време, разгледай този интересен ПР:
https://github.com/jiminny/app/pull/12130
https://github.com/jiminny/app/pull/12130
Today at 1:25:05 PM
1:25
написах supervisor клас AsyncUpdateSupervisor, който се пали от supervisorctl, като тоя клас AsyncUpdateSupervisor пуска два паралелни процеса, един за обработка на активита и втори за обработка на сделки
Today at 1:25:47 PM
1:25
процесите са отделни, за да не се борят за място под слънцето в един и също процес, да можем да им мерим поотделно кой колко памет яде, и съответно да нагласяме размера на всеки batch по тип
Today at 1:26:15 PM...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.54488033,"top":0.1867518,"width":0.022938829,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.016289894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54488033,"top":0.20909816,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54521275,"top":0.23144454,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.041888297,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":19,"bounds":{"left":0.54355055,"top":0.25379092,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.27613726,"width":0.02825798,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.040226065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":17,"bounds":{"left":0.54355055,"top":0.29848364,"width":0.038896278,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.029920213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.32083002,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.023271276,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54355055,"top":0.34317636,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.03158245,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.36552274,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.38786912,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.4102155,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.54421544,"top":0.43256184,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.54421544,"top":0.45490822,"width":0.016289894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.017287234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54454786,"top":0.4772546,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.024601065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.49960095,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.045212764,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.54421544,"top":0.5219473,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.5746209,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.037898935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54488033,"top":0.5969673,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.03324468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54355055,"top":0.61931366,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.030917553,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54488033,"top":0.64166003,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54521275,"top":0.6640064,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.03523936,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.6863527,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54454786,"top":0.7086991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.54488033,"top":0.7310455,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.007978723,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.54521275,"top":0.75339186,"width":0.004986702,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.010305851,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.004654255,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.546875,"top":0.77573824,"width":0.005319149,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.032912236,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.5462101,"top":0.7980846,"width":0.028922873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"bounds":{"left":0.5422208,"top":0.820431,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.820431,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54421544,"top":0.820431,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54488033,"top":0.8427773,"width":0.026928192,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0063164895,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.5767952,"top":0.8427773,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.021941489,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.8954509,"width":0.019946808,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.011635638,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.54454786,"top":0.91779727,"width":0.00930851,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.5422208,"top":0.94014364,"width":0.030585106,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.94014364,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.94014364,"width":0.032912236,"height":0.014365523}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":9,"bounds":{"left":0.60206115,"top":0.09177973,"width":0.030917553,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":11,"bounds":{"left":0.61136967,"top":0.10055866,"width":0.018949468,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.61136967,"top":0.10055866,"width":0.0039893617,"height":0.012769354}},{"char_start":1,"char_count":7,"bounds":{"left":0.61535907,"top":0.10055866,"width":0.014960106,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":10,"bounds":{"left":0.63397604,"top":0.09177973,"width":0.034242023,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":12,"bounds":{"left":0.64328456,"top":0.10055866,"width":0.022273935,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.64328456,"top":0.10055866,"width":0.0033244682,"height":0.012769354}},{"char_start":1,"char_count":9,"bounds":{"left":0.6462766,"top":0.10055866,"width":0.019281914,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":9,"bounds":{"left":0.66921544,"top":0.09177973,"width":0.020944148,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":11,"bounds":{"left":0.67852396,"top":0.10055866,"width":0.008976064,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Pins","depth":9,"bounds":{"left":0.69148934,"top":0.09177973,"width":0.020279255,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Pins","depth":11,"bounds":{"left":0.70079786,"top":0.10055866,"width":0.00831117,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":9,"bounds":{"left":0.71276593,"top":0.09177973,"width":0.010970744,"height":0.030327214},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.015957447,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.007978723,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.013962766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":14,"bounds":{"left":0.7849069,"top":0.12689546,"width":0.025265958,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:00:37 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:00","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"малко по късно и на мен ще ми трябва ревю за един голям feature","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 12:00:46 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:00","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"но ще ти пиша, като е готов за гледане","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":15,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 12:11:37 PM","depth":15,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11 PM","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ок , mersi","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Vasil Vasilev","depth":15,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 1:23:53 PM","depth":15,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:23 PM","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"като имаш време, разгледай този интересен ПР:","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"https://github.com/jiminny/app/pull/12130","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"https://github.com/jiminny/app/pull/12130","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 1:25:05 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:25","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"написах supervisor клас AsyncUpdateSupervisor, който се пали от supervisorctl, като тоя клас AsyncUpdateSupervisor пуска два паралелни процеса, един за обработка на активита и втори за обработка на сделки","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 1:25:47 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:25","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"процесите са отделни, за да не се борят за място под слънцето в един и също процес, да можем да им мерим поотделно кой колко памет яде, и съответно да нагласяме размера на всеки batch по тип","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 1:26:15 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-718788145225758439
|
-8998293804722972854
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 12:00:37 PM
12:00
малко по късно и на мен ще ми трябва ревю за един голям feature
Today at 12:00:46 PM
12:00
но ще ти пиша, като е готов за гледане
(edited)
Lukas Kovalik
Today at 12:11:37 PM
12:11 PM
ок , mersi
Vasil Vasilev
Today at 1:23:53 PM
1:23 PM
като имаш време, разгледай този интересен ПР:
https://github.com/jiminny/app/pull/12130
https://github.com/jiminny/app/pull/12130
Today at 1:25:05 PM
1:25
написах supervisor клас AsyncUpdateSupervisor, който се пали от supervisorctl, като тоя клас AsyncUpdateSupervisor пуска два паралелни процеса, един за обработка на активита и втори за обработка на сделки
Today at 1:25:47 PM
1:25
процесите са отделни, за да не се борят за място под слънцето в един и също процес, да можем да им мерим поотделно кой колко памет яде, и съответно да нагласяме размера на всеки batch по тип
Today at 1:26:15 PM
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringOf Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_.ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu cowoy 1o:1o.1@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis=set(Stestkey, StestValue, "ax, Sttl, "NX*); а така да Sresult = Redis:set(StestKey, StestValue, [nx, 'ex' => Sttl)):Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85277
|
2920
|
18
|
2026-05-28T12:16:19.301258+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970579301_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.56805557,"top":0.0,"width":0.06388889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.56805557,"top":0.0,"width":0.007638889,"height":0.02}},{"char_start":1,"char_count":14,"bounds":{"left":0.57569444,"top":0.0,"width":0.06875,"height":0.02}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":10,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":12,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Pins","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Pins","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":9,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":9,"on_screen":true,"role_description":"text"}]...
|
5904757408954468456
|
-1190753584234652978
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"O ₴4‹$0(ah]БГ100% <78• Thu 28 May 15:16:18181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85276
|
2920
|
17
|
2026-05-28T12:16:15.668576+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970575668_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4955353713447221713
|
-8120951495743817545
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~ffmpeg‹$0(ah]БГ100% <78• Thu 28 May 15:16:15181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85274
|
NULL
|
NULL
|
NULL
|
|
85275
|
2921
|
17
|
2026-05-28T12:16:14.773844+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970574773_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-3811397042041486465
|
-8265137033236236121
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhome CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO› DFieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBEan theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.728)722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_JOTM con Belds + 0M 44• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# hapoy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu cowoy 1o.10.14@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis:set(StestKey, StestValue, 'EX, Stti, "NX"): а така да Sresult = Redis:set(StestKey, StestValue, ['nx, "ex' => $ttl]);Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 3:13 PMShift + Return to add a new in...
|
85273
|
NULL
|
NULL
|
NULL
|
|
85274
|
2920
|
16
|
2026-05-28T12:16:12.378174+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970572378_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"}]...
|
-2917331277012372565
|
-5815000689293182809
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"84‹$0(ah]БГ100% <78• Thu 28 May 15:16:11181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85273
|
2921
|
16
|
2026-05-28T12:16:12.270844+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970572270_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"}]...
|
-3883925369523364552
|
-8120950368302055689
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phgGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityaireoonM AvatalTeallendara Bullhomleosee CopperimermobiacteNacorate A chivinDummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO› DFieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeorcolmererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0String(f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-7471716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M sanicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_AOTM con Brelds 4 0M 4• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron activitiesselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# generall# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu cowoy 1o.lo.@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)Cnhnranic He caRaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis:set(StestKey, StestValue, 'EX, Stti, "NX"): а така да Sresult = Redis:set(StestKey, StestValue, ['nx, "ex' => $ttl]);Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMnau e ann/Services/Grm/Hubsnot/Glient oho:101Vasil Vasiley 314 pvwe to ononnsShift + Return to add a new in...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85272
|
2920
|
15
|
2026-05-28T12:16:11.362688+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970571362_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeRefactorRunToolsGi PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"€ 84‹$0(ah]БГ100% <78• Thu 28 May 15:16:10181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
1062495680602691476
|
NULL
|
typing_pause
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeRefactorRunToolsGi PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"€ 84‹$0(ah]БГ100% <78• Thu 28 May 15:16:10181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85270
|
NULL
|
NULL
|
NULL
|
|
85271
|
2921
|
15
|
2026-05-28T12:16:09.565174+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970569565_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 12:00:37 PM
12:00
малко по късно и на мен ще ми трябва ревю за един голям feature
Today at 12:00:46 PM
12:00
но ще ти пиша, като е готов за гледане
(edited)
Lukas Kovalik...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.09736632,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54521275,"top":0.09736632,"width":0.015292553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.010638298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.11971269,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.54521275,"top":0.11971269,"width":0.00731383,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.14205906,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54454786,"top":0.14205906,"width":0.032247342,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.025265958,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.16440542,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54521275,"top":0.16440542,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.1867518,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.54488033,"top":0.1867518,"width":0.022938829,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.016289894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.20909816,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54488033,"top":0.20909816,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54521275,"top":0.23144454,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.041888297,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.25379092,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":19,"bounds":{"left":0.54355055,"top":0.25379092,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.27613726,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.27613726,"width":0.02825798,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.040226065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.29848364,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":17,"bounds":{"left":0.54355055,"top":0.29848364,"width":0.038896278,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.029920213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.32083002,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54355055,"top":0.32083002,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.023271276,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.34317636,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54355055,"top":0.34317636,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.03158245,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.36552274,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.36552274,"width":0.028590426,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.38786912,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.38786912,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4102155,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54521275,"top":0.4102155,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.43256184,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.54421544,"top":0.43256184,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.018284574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.45490822,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.54421544,"top":0.45490822,"width":0.016289894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.017287234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.4772546,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.54454786,"top":0.4772546,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.024601065,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.49960095,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.49960095,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.045212764,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5219473,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.54421544,"top":0.5219473,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5746209,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54521275,"top":0.5746209,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.037898935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.5969673,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.54488033,"top":0.5969673,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.03324468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.61931366,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54355055,"top":0.61931366,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.030917553,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.64166003,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54488033,"top":0.64166003,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6640064,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54521275,"top":0.6640064,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.03523936,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.6863527,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.6863527,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7086991,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.54454786,"top":0.7086991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7310455,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.54488033,"top":0.7310455,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.007978723,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.75339186,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.54521275,"top":0.75339186,"width":0.004986702,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.010305851,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.77573824,"width":0.004654255,"height":0.014365523}},{"char_start":1,"char_count":3,"bounds":{"left":0.546875,"top":0.77573824,"width":0.005319149,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.032912236,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.7980846,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.5462101,"top":0.7980846,"width":0.028922873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"bounds":{"left":0.5422208,"top":0.820431,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.820431,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.54421544,"top":0.820431,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.029587766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8427773,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.54488033,"top":0.8427773,"width":0.026928192,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0063164895,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5744681,"top":0.8427773,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.5767952,"top":0.8427773,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.021941489,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.8954509,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.54421544,"top":0.8954509,"width":0.019946808,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.011635638,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.91779727,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.54454786,"top":0.91779727,"width":0.00930851,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.5422208,"top":0.94014364,"width":0.030585106,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5422208,"top":0.94014364,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.54587764,"top":0.94014364,"width":0.032912236,"height":0.014365523}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":9,"bounds":{"left":0.60206115,"top":0.09177973,"width":0.030917553,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":11,"bounds":{"left":0.61136967,"top":0.10055866,"width":0.018949468,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.61136967,"top":0.10055866,"width":0.0039893617,"height":0.012769354}},{"char_start":1,"char_count":7,"bounds":{"left":0.61535907,"top":0.10055866,"width":0.014960106,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":10,"bounds":{"left":0.63397604,"top":0.09177973,"width":0.034242023,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":12,"bounds":{"left":0.64328456,"top":0.10055866,"width":0.022273935,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.64328456,"top":0.10055866,"width":0.0033244682,"height":0.012769354}},{"char_start":1,"char_count":9,"bounds":{"left":0.6462766,"top":0.10055866,"width":0.019281914,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":9,"bounds":{"left":0.66921544,"top":0.09177973,"width":0.020944148,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":11,"bounds":{"left":0.67852396,"top":0.10055866,"width":0.008976064,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Pins","depth":9,"bounds":{"left":0.69148934,"top":0.09177973,"width":0.020279255,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Pins","depth":11,"bounds":{"left":0.70079786,"top":0.10055866,"width":0.00831117,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":9,"bounds":{"left":0.71276593,"top":0.09177973,"width":0.010970744,"height":0.030327214},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.015957447,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.007978723,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":9,"bounds":{"left":0.59640956,"top":0.0518755,"width":0.013962766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":14,"bounds":{"left":0.7849069,"top":0.12689546,"width":0.025265958,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:00:37 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:00","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"малко по късно и на мен ще ми трябва ревю за един голям feature","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 12:00:46 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:00","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"но ще ти пиша, като е готов за гледане","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":15,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5745807010385653348
|
-8125704643672957110
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 12:00:37 PM
12:00
малко по късно и на мен ще ми трябва ревю за един голям feature
Today at 12:00:46 PM
12:00
но ще ти пиша, като е готов за гледане
(edited)
Lukas Kovalik
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-proidetecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phpGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho> (l Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityAiReodrM AvatalTeallendara Bullhome CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:EBE31532631731888an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringOf Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexojinesAt.722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans, wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_AOTM con Brelds 4 0M 4• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron activitiesselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY ….# backend# buescontusion-dinig# donut_time#enpineerine# general# hapoy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamatol1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0% L7Inu cowoy 1o:1o.0@ Describe what you are looking forVasil Vasileve MessagerNoR0d canvis7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis:set(StestKey, StestValue, 'EX, Stti, "NX"): а така да Sresult = Redis:set(StestKey, StestValue, ['nx, "ex' => $ttl]);Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMShift + Return to add a new in...
|
85268
|
NULL
|
NULL
|
NULL
|
|
85270
|
2920
|
14
|
2026-05-28T12:16:09.436295+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970569436_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 12:00:37 PM
12:00
малко по късно и на мен ще ми трябва ревю за един голям feature
Today at 12:00:46 PM
12:00
но ще ти пиша, като е готов за гледане
(edited)
Lukas Kovalik...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"donut_time","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"happy_birthday","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infosec_internal_all","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"infrastructure_dev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jbu-team-info","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-team","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Iliyana Netseva","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mira","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":15,"bounds":{"left":0.56805557,"top":0.0,"width":0.06388889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.56805557,"top":0.0,"width":0.007638889,"height":0.02}},{"char_start":1,"char_count":14,"bounds":{"left":0.57569444,"top":0.0,"width":0.06875,"height":0.02}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":10,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":12,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Pins","depth":9,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Pins","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":9,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":14,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:00:37 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:00","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"малко по късно и на мен ще ми трябва ревю за един голям feature","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Today at 12:00:46 PM","depth":16,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:00","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"но ще ти пиша, като е готов за гледане","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":16,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":15,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5745807010385653348
|
-8125704643672957110
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
donut_time
engineering
general
happy_birthday
infosec_internal_all
infra-changes
infrastructure_dev
jbu-team-info
jiminny-bg
platform-team
platform-tickets
product_launches
random
releases
support
thank-yous
the_people_of_jiminny
Vasil Vasilev
Stefka Stoyanova
Iliyana Netseva
Stoyan Tomov
Petko Kashinski
Galya Dimitrova
Todor Stamatov
Steliyan Georgiev
Ves
Mira
Nikolay Yankov
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Pins
Pins
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 12:00:37 PM
12:00
малко по късно и на мен ще ми трябва ревю за един голям feature
Today at 12:00:46 PM
12:00
но ще ти пиша, като е готов за гледане
(edited)
Lukas Kovalik
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"€ 884‹$0(ah]БГ100% <78• Thu 28 May 15:16:09181ec2-user@ip-10-30-140-….₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
85269
|
2920
|
13
|
2026-05-28T12:16:06.163081+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970566163_m1.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-backend-engineers","depth":15,"on_screen":false,"role_description":"text"}]...
|
-8276566832937135362
|
-8141359511730962697
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
platform-backend-engineers
PhpStormFileEditViewNavigateCodeRefactorRunToolsGitWindowHelpec2-user@ip-10-30-129-190:~screenpipe"€ 84‹$0(ah]A100% <78• Thu 28 May 15:16:05181ec2-user@ip-10-30-140-...₴7DOCKER#_####_#####\\###||\#/V~'881DEV (-zsh)O [EMAIL] Linux 2023 (ECS Optimized)_/m/For documentation, visit [URL_WITH_CREDENTIALS] ~]$ exitlogoutConnection to jiminny-prod-ecsi closed.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ applukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ vprodWarning: Permanently added 'jiminny-prod-ecs1' (ED25519) to the list of known hosts.A newer release of "Amazon Linux" is available.Version 2023.10.20260330:Version 2023.11.20260406:Version 2023.11.20260413:Version2023.11.20260427:Version2023.11.20260505:Version 2023.11.20260509:Version 2023.11.20260511:Version 2023.11.20260514:Run "/usr/bin/dnf check-release-update" for full release and version update info#_~\ ####_\ #####\\###1\#/Amazon Linux 2023 (ECS Optimized)/m/'For documentation, visit [URL_WITH_CREDENTIALS] ~]$ client_loop: send disconnect: Broken pipeukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20915-fix-missing-header-text-relay) $I...
|
85267
|
NULL
|
NULL
|
NULL
|
|
85268
|
2921
|
14
|
2026-05-28T12:16:05.064014+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-28/1779 /Users/lukas/.screenpipe/data/data/2026-05-28/1779970565064_m2.jpg...
|
Slack
|
Vasil Vasilev (DM) - Jiminny Inc - 3 new items - S Vasil Vasilev (DM) - Jiminny Inc - 3 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":6,"bounds":{"left":0.5056516,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":6,"bounds":{"left":0.50299203,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":8,"bounds":{"left":0.50664896,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":6,"bounds":{"left":0.50299203,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":8,"bounds":{"left":0.50764626,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":6,"bounds":{"left":0.50299203,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":8,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.5053192,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.50764626,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":6,"bounds":{"left":0.50299203,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":8,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50797874,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5099734,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":6,"bounds":{"left":0.50299203,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":8,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.5093085,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":6,"bounds":{"left":0.50299203,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":8,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.50731385,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.5106383,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":13,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":13,"on_screen":false,"role_description":"text"}]...
|
8802802765596083200
|
-8129993884726510929
|
typing_pause
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
SIUCKVIChRotonWindowHelpPwovscors#12121 on JY-20963-foc-Proinet vecanyice ph.ne beloers.ohtpelereooiecistraiconSamiceTesuphr©ActivityControlier.php=custom.loglaravel.log© VoiceConsentPrefix.phpen Noticationsv Observers© AccountObserver.phcCActwwooserver.pnp© ContactObserver.phpGroupObserver.pho© LeadObserver.phoC ProfileObserver.phpC SocialAccountObserver.php© UserObserver.phoUserRoleObserver.pho(in Policiesa ProvidersCn Queue› E RepositoriosCn RulesvserviceDa ActivityaireoonM Avatallealendara Bullhome CopperimermobiacteNacorate A chivin>@ Dummym Helnarsv im Hibsod(i) AccountSyncStrategMAetionet ContactSyncStrateay› DDTO> Ea Fieldswn taueeaOLeAkоkyScrco.onO UserSHStoy-prp© Team.phpe KecneupnisA console [STAGINGTeareolaocererestonC TextRelayServiceTest.phg(©) Hubspot.JournalPollinaService.ohp x ptp autoload.ohrcass nuosoorsournalroco noserveana lock to orevent auloole instances3073esepolsinalocko: bool— 78%78578705786›addSeconds(self::LOCK_VTL_SECONDS) ->tolS0StringO:an theat hothtoek ann ayns.matsondtCoyns noeht> now()->toIS0StringO317318f Not eXists) for atonic lock acquisitionis::set(key: self::POLLING LOCK KEY, ison encode(SlockData), options: 'EX", self::LOCK TTL SECONDS, *NX*)=88711712=213-74715716717-218Renewal = tineo,100: "[HubSpot Journal Polbingl Acquired polting lock".[• => SexoinesAt.722723$ 332933133373PolLinglock@= woidt733C UTHAAAARAAAA734@ HubspotDeaMohhonie 346735(C) Hubspot.JournalApiClielLing lock (for emergency situations)© Hubspot.JournalPolling! 348@ HubspotWebhookSubr© .JournalAoiResutt.oho› LeaseLock(): voidf...}© JournalBatchSizelimitEC) Journa Eventtranstormervice to stop gracefullya Metadata@poortunityswncstrateo→lmlpae natioo• Stop@: void(...}M canicetraiteTX: AUTONAND a.created_at › DATE_:GROUP BY u.id, u.email,ORDER BY sns_count DESCselect + Eron teans, wherlselect + Eron coles.CEIEOTCONCATU.Id, CASE WHsa.*t.ouner id FROM sociJOIN users u on u.id = sJOIN teans tWHERE u.tean_id = 1117 aSELECT * FROM actávitioSELECT * FROM actávitioSELECT * FROM crn configSELECT * FROM teans WHERselleetron usens whenselect * fron playbooksseleetron miawhonkdselect * fron playbook_ctselleet ron eoselselect * fron crn_field.vSELECT * FROM crn_field_AOTM con Brelds 4 0M 4• JOIN activities a ON €NHERF Actvity d = 7002AAND € eon onoviden salSELECT * FROM activitymselect * fron text relayselect * fron activitiesselect * fron users whenPARAtT GAAR MANGUREANOPAlRetGhAn dAAAIRdAMohnttene neard whardselect * fron teans wherPhat"toon actiytysselect * fron activitysDMsActivityLateMonJiminnY …# backend# buescontusion-dinig# donut_time#enpineerine# general# happy birthdavA infocoe intemal all# infra-chansed# infrastructure de#bu-team-infoi liminnv-best olatform-team# platform-ticketstoroduct launche# random# release# suppor# thank-youssie the neoole of fimil6? Direct message.Vasil VasilenF8. Stefka Stoyanova1a llivana NetsevaA Ctovan TomnulPetko Kashinski( Galva Dimitrova P: Todor Stamator1 Stelivan Georsie.D Vod&r MireNikolav Vanko&. James GrahamLukas KovalkyTO0%7AInu cowoy 1o.lo.0"@ Describe what you are looking forVasil Vasileve MessagerNoRdd canv7 Files+Vasil Vasilev 2:56 PM1 с добър коментарDoory2e intentionaЗ сьщо e intentional поради факта, че phpredis dniver-a не поддьржа set ex +nх параметри, и тряова да се пуснат две операции set + expireLukas Kovalik 3.07 PMок, зз го пуснах пак поез gеmіnіlза третата точка обаче наистина ли няма подьржкааз май си ги ползвам някьлеVasil Vasilev 3:10 PMне става, бях го направил така, и се счупиLukas Kovalik 3:10 PMами и при мен се чумешеVasil Vasilev 3:11 PMpredis поддьржа set(Skey. Svalue. nx' - true, ex =60)C nanreric He caeaLukas Kovalik 3.14pNтака май не работеше Sresult = Redis:set(StestKey, StestValue, 'EX, Stti, "NX"): а така да Sresult = Redis:set(StestKey, StestValue, ['nx, "ex' => $ttl]);Vasil Vasiley 2.11 pwLukas Kovalik 3.12 pNне помно BеUEVasil Vasilev 3:12 PMobоитноtо може nаeLukas Kovalik 3-12 PMможе и ла брькамVacil Vaciley 242 pwewons uusSlockAcquired - Redis::set(self::POLLING LOCK KEY, ison encode(SlockData). "EX', self::LOCK TTL SECONDS. *NX*))значи пьрвото работиLukas Kovalik 313 PMwe to ononnsShift + Return to add a new in...
|
NULL
|
NULL
|
NULL
|
NULL
|