|
55316
|
1914
|
62
|
2026-05-18T14:01:45.148394+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112905148_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":2,"bounds":{"left":0.7826389,"top":0.0,"width":0.14513889,"height":0.015555556},"on_screen":true,"role_description":"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"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":"1","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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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":"New File or Directory…","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}]...
|
-489463679308102652
|
-259430539844874275
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…...
|
55315
|
NULL
|
NULL
|
NULL
|
|
55317
|
1915
|
30
|
2026-05-18T14:01:46.407405+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112906407_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"","depth":2,"bounds":{"left":0.6449468,"top":0.92098963,"width":0.06948138,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":2,"bounds":{"left":0.6449468,"top":0.952913,"width":0.06948138,"height":0.011173184},"on_screen":true,"role_description":"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":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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.8081782,"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":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"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 'AskJiminnyReportActivityServiceTest'","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 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"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":"1","depth":4,"bounds":{"left":0.7124335,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.72140956,"top":0.09896249,"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.7287234,"top":0.09896249,"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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"bounds":{"left":0.4481383,"top":0.09736632,"width":0.29288563,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-819186497728337901
|
-259430539844874275
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}...
|
55309
|
NULL
|
NULL
|
NULL
|
|
55318
|
1914
|
63
|
2026-05-18T14:01:48.173799+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112908173_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":2,"bounds":{"left":0.7826389,"top":0.0,"width":0.14513889,"height":0.015555556},"on_screen":true,"role_description":"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"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":"1","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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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":"New File or Directory…","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":"Expand Selected","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}]...
|
6765114288521301901
|
-259430402405920803
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55319
|
1914
|
64
|
2026-05-18T14:01:51.184030+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112911184_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":2,"bounds":{"left":0.7826389,"top":0.0,"width":0.14513889,"height":0.015555556},"on_screen":true,"role_description":"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"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}]...
|
7870932135135850543
|
-1414059449786593327
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes...
|
55318
|
NULL
|
NULL
|
NULL
|
|
55320
|
1914
|
65
|
2026-05-18T14:01:57.243610+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112917243_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% C8 • Mon 18 May 17:01:5740 5••Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:01 PM | [Platform] Refinement®1:48:24...
|
NULL
|
-1562962791521282002
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% C8 • Mon 18 May 17:01:5740 5••Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:01 PM | [Platform] Refinement®1:48:24...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55321
|
1915
|
31
|
2026-05-18T14:01:59.202989+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112919202_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"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":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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.8081782,"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":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"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 'AskJiminnyReportActivityServiceTest'","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 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","depth":4,"bounds":{"left":0.7124335,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.72140956,"top":0.09896249,"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.7287234,"top":0.09896249,"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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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":"New File or Directory…","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":"Expand Selected","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":"Collapse All","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":"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}]...
|
8729639483820449576
|
-259430402414309411
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55322
|
1914
|
66
|
2026-05-18T14:02:00.297559+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112920297_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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":"New File or Directory…","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":"Expand Selected","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":"Collapse All","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":"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}]...
|
8729639483820449576
|
-259430402414309411
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
55320
|
NULL
|
NULL
|
NULL
|
|
55323
|
1914
|
67
|
2026-05-18T14:02:09.354180+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112929354_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…...
|
[{"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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":"New File or Directory…","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}]...
|
-489463679308102652
|
-259430539844874275
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55324
|
1914
|
68
|
2026-05-18T14:02:12.372117+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112932372_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1...
|
[{"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","depth":4,"on_screen":true,"role_description":"text"}]...
|
-3808038276909421723
|
-1414059449787118639
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1...
|
55323
|
NULL
|
NULL
|
NULL
|
|
55325
|
1914
|
69
|
2026-05-18T14:02:15.413032+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112935413_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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":"New File or Directory…","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":"Expand Selected","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":"Collapse All","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":"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}]...
|
8729639483820449576
|
-259430402414309411
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55326
|
1914
|
70
|
2026-05-18T14:02:21.448553+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112941448_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project...
|
[{"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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"}]...
|
-2505221281714706024
|
-259430539844874275
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project...
|
55325
|
NULL
|
NULL
|
NULL
|
|
55327
|
1914
|
71
|
2026-05-18T14:02:24.459358+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112944459_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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":"New File or Directory…","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":"Expand Selected","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":"Collapse All","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":"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}]...
|
8729639483820449576
|
-259430402414309411
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55328
|
1914
|
72
|
2026-05-18T14:02:27.540777+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112947540_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistory→BookmarksProfilesToolsW FirefoxFileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% C8 • Mon 18 May 17:02:275Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:48:54...
|
NULL
|
1612724823432948214
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistory→BookmarksProfilesToolsW FirefoxFileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% C8 • Mon 18 May 17:02:275Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:48:54...
|
55327
|
NULL
|
NULL
|
NULL
|
|
55329
|
1915
|
32
|
2026-05-18T14:02:29.516003+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112949516_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…...
|
[{"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":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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.8081782,"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":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"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 'AskJiminnyReportActivityServiceTest'","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 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","depth":4,"bounds":{"left":0.7124335,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.72140956,"top":0.09896249,"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.7287234,"top":0.09896249,"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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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":"New File or Directory…","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}]...
|
-489463679308102652
|
-259430539844874275
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…...
|
55321
|
NULL
|
NULL
|
NULL
|
|
55330
|
1914
|
73
|
2026-05-18T14:02:30.499164+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112950499_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections...
|
[{"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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}]...
|
-7429716278976468786
|
-8636355650190325311
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
Firefox• 0FileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kova100% <78 • Mon 18 May 17:02:30)%40jiminny.comA05Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:48:57...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55331
|
1914
|
74
|
2026-05-18T14:02:31.659421+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112951659_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFile•0 0Edit→ViewHistoryBookmarksProfilesTo FirefoxFile•0 0Edit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% C8 • Mon 18 May 17:02:31|=A05Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:48:58...
|
NULL
|
-5949475179249660223
|
NULL
|
click
|
ocr
|
NULL
|
FirefoxFile•0 0Edit→ViewHistoryBookmarksProfilesTo FirefoxFile•0 0Edit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% C8 • Mon 18 May 17:02:31|=A05Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:48:58...
|
55330
|
NULL
|
NULL
|
NULL
|
|
55332
|
1915
|
33
|
2026-05-18T14:02:31.659605+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112951659_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormINavicarecodeLaravelKeractorFV faVsco.js?9 PhostormINavicarecodeLaravelKeractorFV faVsco.js?9 master kroledey(c) ReindexForUserJob.pnpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_A keDors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.oo.onvc) SendReoortNotGeneratedMail.loo.ondCalendarv 17Cmm› M Delete> M Hubsoot> IM Salesforce(c) Autoloabelavedtocrm.nhnl(C) CheckAndRetrvRemoteMatch.nhnWiminnyServices Activitv RinaCentral Service.imoortData in.X.• Mothadl(m d importData service ...app/Services/Activity RinqCentral• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resultiv D app/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul100% 2• Mon 18 May 17:02:31C BaseService.pnp© SoftPhoneManager.phpC) CoreUserRequest.pnpscimProvistoning.ong© CoreUser.php© Activity/Close/service.pnp© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueorivatetunction runor ActivtvmoortResult$this->import->getEndDateO$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])Sthis->import->getActivityIdOrecurn (new Acciv1cylmporckesulcoo-›secToraLsimporceokecoros->addimportedSimportedRecords)private function complete(ActivityImportResult $result): void= custom.log= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]# console [euyA console [STAGING)© CoachingFeedbackCoachUserln.php xfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini~__construct(UserRepository $userRepository)(...}29 O;public function shouldApplyQueries: bool{...}34 đt >public function getQueries: FilterDefinitionQueryCollection{...}45 gtpublic function toArrayO: arrayf...}private function getOptionsO: arrayf...}118119public function getValue@: array{...}1lusadeprivate function aetDefaultValue@): arravf...?136 Ct>nublic function aetValidationRules(2strina Sprefix = null): arravf...}Sservice->setDebua(Sthis->imnort->runsInDebuaob:Sthis->service = Sservice:nnivate function nuno• Activitvimnon+Recultsthis-sloagen-sinfor:/SvncActivitvl Stanti Sthis->conteyt)•Sthis-sactivitvtmnontMananen.sctant/Sthic-simnont)•SimportedRecords = $this->service->importData($this->import->getStartDateO,$this->import->getEndDateOSthis->userRepository->findOneBy(['id' => Sthis->import->getUserIdOl).Sthis->import->qetActivitvIdoreturn (new ActivityImportResulto)->setTotal(SimportedRecords)->addImported(SimportedRecords)private function complete(ActivityImportResult Sresult): void$this->activitvImnortManager->complete($this->imnort. Sresult):Datadog: : increment( stats: 'jiminny.activity.sync.success', sampleRate:1.0, [Call HierarchtCascadeImplement Trial OwneFixing Redis Rate LimiXSalestorce Token FalliWARN Metadata found iin doc-comment for method9/ 10 tacke doneo fileses/ L ListenerkoiecannotHaveAaminurManagerrermissionkule.pnp +39app/Comoonent/SCIM/=Constants.ono +3se/ u CoreUser.phpann/Comnonent/SCIM/Mutatore/Attributes/Ucer/M PoleAtr.nbn 4171ites/User/ RoleAttrTest.php +224ann/DTO/SCIMIAAD/Request/MCoreUserRequest.ohn t15Ask anvthina (*4L1+ <> Code SWE-1.6SClM Role Manageme+0 ..inp on LineView all* Reject allAccent alllWN Windsurf Toams 165•66UTF.8io 4 spaces 0...
|
NULL
|
8186099307263540173
|
NULL
|
click
|
ocr
|
NULL
|
PhostormINavicarecodeLaravelKeractorFV faVsco.js?9 PhostormINavicarecodeLaravelKeractorFV faVsco.js?9 master kroledey(c) ReindexForUserJob.pnpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_A keDors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.oo.onvc) SendReoortNotGeneratedMail.loo.ondCalendarv 17Cmm› M Delete> M Hubsoot> IM Salesforce(c) Autoloabelavedtocrm.nhnl(C) CheckAndRetrvRemoteMatch.nhnWiminnyServices Activitv RinaCentral Service.imoortData in.X.• Mothadl(m d importData service ...app/Services/Activity RinqCentral• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resultiv D app/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul100% 2• Mon 18 May 17:02:31C BaseService.pnp© SoftPhoneManager.phpC) CoreUserRequest.pnpscimProvistoning.ong© CoreUser.php© Activity/Close/service.pnp© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueorivatetunction runor ActivtvmoortResult$this->import->getEndDateO$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])Sthis->import->getActivityIdOrecurn (new Acciv1cylmporckesulcoo-›secToraLsimporceokecoros->addimportedSimportedRecords)private function complete(ActivityImportResult $result): void= custom.log= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]# console [euyA console [STAGING)© CoachingFeedbackCoachUserln.php xfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini~__construct(UserRepository $userRepository)(...}29 O;public function shouldApplyQueries: bool{...}34 đt >public function getQueries: FilterDefinitionQueryCollection{...}45 gtpublic function toArrayO: arrayf...}private function getOptionsO: arrayf...}118119public function getValue@: array{...}1lusadeprivate function aetDefaultValue@): arravf...?136 Ct>nublic function aetValidationRules(2strina Sprefix = null): arravf...}Sservice->setDebua(Sthis->imnort->runsInDebuaob:Sthis->service = Sservice:nnivate function nuno• Activitvimnon+Recultsthis-sloagen-sinfor:/SvncActivitvl Stanti Sthis->conteyt)•Sthis-sactivitvtmnontMananen.sctant/Sthic-simnont)•SimportedRecords = $this->service->importData($this->import->getStartDateO,$this->import->getEndDateOSthis->userRepository->findOneBy(['id' => Sthis->import->getUserIdOl).Sthis->import->qetActivitvIdoreturn (new ActivityImportResulto)->setTotal(SimportedRecords)->addImported(SimportedRecords)private function complete(ActivityImportResult Sresult): void$this->activitvImnortManager->complete($this->imnort. Sresult):Datadog: : increment( stats: 'jiminny.activity.sync.success', sampleRate:1.0, [Call HierarchtCascadeImplement Trial OwneFixing Redis Rate LimiXSalestorce Token FalliWARN Metadata found iin doc-comment for method9/ 10 tacke doneo fileses/ L ListenerkoiecannotHaveAaminurManagerrermissionkule.pnp +39app/Comoonent/SCIM/=Constants.ono +3se/ u CoreUser.phpann/Comnonent/SCIM/Mutatore/Attributes/Ucer/M PoleAtr.nbn 4171ites/User/ RoleAttrTest.php +224ann/DTO/SCIMIAAD/Request/MCoreUserRequest.ohn t15Ask anvthina (*4L1+ <> Code SWE-1.6SClM Role Manageme+0 ..inp on LineView all* Reject allAccent alllWN Windsurf Toams 165•66UTF.8io 4 spaces 0...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55333
|
1914
|
75
|
2026-05-18T14:02:33.604780+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112953604_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% <78 • Mon 18 May 17:02:33)=A05Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:49:00...
|
NULL
|
-7169632165961508660
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% <78 • Mon 18 May 17:02:33)=A05Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:49:00...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55334
|
1915
|
34
|
2026-05-18T14:02:34.323140+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112954323_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
|
[{"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}]...
|
8043719072324535154
|
-8628527368849355612
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
PhostormINavicarecodeLara Project: faVsco.js, menu
PhostormINavicarecodeLaravelKeractorFV faVsco.js?9 master kroledey@) PeindexForUserJob.ongketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_A keDors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.ohoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.onvCalendarv 17Cmm› M Delete> M Hubsoot> IM Salesforce(c) Autoloabelavedtocrm.nhnlFindWiminny) Services Activitv RinaCentral Service.imoortData in . X.• Mothadl(m d importData service ...app/services/Activity RinaCentra• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resultiv D app/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul100% 2• Mon 18 May 17:02:33AskJiminnyReportActivityServiceTest vFixing Redis Rate LimixSalestorce Token FalliSClM Role Manageme+0 ..C BaseService.pnp© SoftPhoneManager.phpC) CoreUserRequest.pnpscimProvistoning.ong© CoreUser.php© Activity/Close/service.pnp© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueorivatetunction runor ActivtvmoortResult$this->import->getEndDateO$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])Sthis->import->getActivityIdOrecurn (new Acciv1cylmporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)private function complete(ActivityImportResult $result): void= custom.log= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]& console [EU]CascadeA console [STAGING)© CoachingFeedbackCoachUserln.php XImplement Trial Ownefinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini~__construct(UserRepository $userRepository)(...}29 O;public function shouldApplyQueries: bool{...}34 đt >public function getQueries: FilterDefinitionQueryCollection{...}45 gtpublic function toArrayO: arrayf...}private function getOptionsO: arrayf...}118119public function getValue@: array{...}1301usadeprivate function aetDefaultValue@): arravf...?136 Ct>public function getValidationRules(?string $prefix = null): arrayf...}+ <> Code SWE-1.6Sservice->setDebug(Sthis->import->runsInDebua)Sthic-scenvice = Sservice:private function run®: ActivityImportResultSthis->loager->info('[SvncActivitv] Start'. Sthis->context):Sthis->activitvImoortMarader->startsthas->import):SimportedRecords = Sthis->service->importDatadSthis->import->getStartDateO,sthis->imoort->aetEndDateo.$this->userRepository->findOneBy(['id' => $this->import->getUserIdO]),Sthis-simnont->aetActivitvIddneturninew_ActivitvImnontResultonl>setTotal(SimnontedRecords)-SaddTmnonted(SimnontedRecords)Constants.oo +3e/ u coreUser.php10 RoleAttr.ohp +171es/User/ D RoleAttrTest.php +224* Reject all• Accent alliprivate function complete(ActivityImportResult Sresult): voic$this-›activityImportManager->complete($this->import, $result):Datadog: : increment( stats: 'jiminny.activity.sync.success', sampleRate: 1.0, lCall HierarchtW Windsurf Teams 165:66 UTF-8 P 4 spaces ®...
|
55332
|
NULL
|
NULL
|
NULL
|
|
55335
|
1914
|
76
|
2026-05-18T14:02:36.615729+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112956615_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}...
|
[{"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":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
3303896123807886662
|
-1423066649041924143
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}...
|
55333
|
NULL
|
NULL
|
NULL
|
|
55336
|
1915
|
35
|
2026-05-18T14:02:37.336038+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112957336_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project...
|
[{"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":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>114 incoming commits<br/>","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.8081782,"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":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"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 'AskJiminnyReportActivityServiceTest'","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 'AskJiminnyReportActivityServiceTest'","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":"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":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Activity;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Component\\Sentry\\SentryClient;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Contracts\\Services\\ImportsDataInterface;\nuse Jiminny\\DTO\\Activity\\Import\\ActivityImportResult;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity\\ActivityImport;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Services\\Activity\\ActivityProviderRegistry;\nuse Jiminny\\Services\\Import\\ActivityImportManager;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\nclass SyncActivity extends Job implements ShouldQueue\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';\n\n public int $tries = 3;\n public $queue = Constants::QUEUE_DIALERS;\n\n private ActivityImport $import;\n private ?ActivityImportManager $activityImportManager = null;\n private ?UserRepository $userRepository = null;\n private ?SentryClient $sentryClient = null;\n private ?LoggerInterface $logger = null;\n private ?Provider $provider = null;\n private ?ImportsDataInterface $service = null;\n private array $context;\n\n public function __construct(ActivityImport $import)\n {\n $this->import = $import;\n $this->context = ['import_id' => $import->getId()];\n }\n\n public function handle(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n try {\n $this->init(\n $activityImportManager,\n $activityProviderRegistry,\n $userRepository,\n $sentry,\n $logger,\n );\n } catch (Throwable $exception) {\n $this->failImport($exception);\n\n return;\n }\n\n Datadog::increment('jiminny.activity.sync.start', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n try {\n $result = $this->run();\n $this->complete($result);\n } catch (Throwable $exception) {\n $this->failImport($exception);\n }\n }\n\n public function failed(Throwable $exception): void\n {\n $this->logger ??= app(LoggerInterface::class);\n $this->activityImportManager ??= app(ActivityImportManager::class);\n $this->sentryClient ??= app(SentryClient::class);\n\n if (! isset($this->context)) {\n // This can happen in case of improper deserialization.\n $this->context = [];\n }\n $this->context['team'] ??= 'unknown';\n $this->context['provider'] ??= 'unknown';\n\n if (isset($this->import)) {\n // This can happen in case of improper deserialization.\n $this->failImport($exception);\n }\n }\n\n /**\n * @throws ActivityProviderException\n * @throws SocialAccountTokenInvalidException\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n */\n private function init(\n ActivityImportManager $activityImportManager,\n ActivityProviderRegistry $activityProviderRegistry,\n UserRepository $userRepository,\n SentryClient $sentry,\n LoggerInterface $logger,\n ): void {\n $this->logger = $logger;\n $this->activityImportManager = $activityImportManager;\n $this->userRepository = $userRepository;\n $this->sentryClient = $sentry;\n $provider = $this->import->getActivityProvider();\n\n $this->context['provider'] = $provider->getProviderSlug();\n $this->context['provider_id'] = $provider->getId();\n $this->context['team'] = $provider->getTeam()->getSlug();\n $this->context['team_id'] = $provider->getTeamId();\n\n if (! $provider->isEnabled()) {\n throw new ActivityProviderException('Activity provider is disabled', $provider);\n }\n\n $this->provider = $provider;\n $service = $activityProviderRegistry->get($provider->getProviderSlug());\n\n if (! $service instanceof ImportsDataInterface) {\n throw new ActivityProviderException('Activity provider does not support data imports', $provider);\n }\n\n $service->setTeam($provider->getTeam());\n $service->setSocialAccount($provider->getConnectedSocialAccount());\n $service->setDebug($this->import->runsInDebug());\n $this->service = $service;\n }\n\n private function run(): ActivityImportResult\n {\n $this->logger->info('[SyncActivity] Start', $this->context);\n $this->activityImportManager->start($this->import);\n\n $importedRecords = $this->service->importData(\n $this->import->getStartDate(),\n $this->import->getEndDate(),\n $this->userRepository->findOneBy(['id' => $this->import->getUserId()]),\n $this->import->getActivityId()\n );\n\n return (new ActivityImportResult())\n ->setTotal($importedRecords)\n ->addImported($importedRecords)\n ;\n }\n\n private function complete(ActivityImportResult $result): void\n {\n $this->activityImportManager->complete($this->import, $result);\n\n Datadog::increment('jiminny.activity.sync.success', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n ]);\n\n $this->logger->info('[SyncActivity] End', $this->context);\n\n $this->logger->info(\n '[SyncActivity] Memory usage',\n array_merge(\n $this->context,\n [\n 'memory_usage' => memory_get_usage(),\n 'memory_real_usage' => memory_get_usage(true),\n 'pid' => getmypid(),\n ],\n ),\n );\n }\n\n private function failImport(Throwable $exception): void\n {\n $this->logger->alert(\n message: '[SyncActivity] Failed',\n context: array_merge($this->context, [\n 'reason' => $exception->getMessage(),\n 'file' => $exception->getFile(),\n 'line' => $exception->getLine(),\n ]),\n );\n\n $this->activityImportManager->fail($this->import);\n\n Datadog::increment('jiminny.activity.sync.exception', 1.0, [\n 'company' => $this->context['team'],\n 'provider' => $this->context['provider'],\n 'exception' => $exception::class,\n 'exceptionCode' => $exception->getCode(),\n ]);\n\n if ($exception instanceof SocialAccountTokenInvalidException) {\n return;\n }\n\n $this->sentryClient->captureException($exception);\n }\n}","role_description":"text entry area","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":"1","depth":4,"bounds":{"left":0.7124335,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.72140956,"top":0.09896249,"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.7287234,"top":0.09896249,"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\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","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"}]...
|
-2505221281714706024
|
-259430539844874275
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Activity;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Jiminny\Component\Queue\Constants;
use Jiminny\Component\Sentry\SentryClient;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Contracts\Services\ImportsDataInterface;
use Jiminny\DTO\Activity\Import\ActivityImportResult;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity\ActivityImport;
use Jiminny\Models\Activity\Provider;
use Jiminny\Services\Activity\ActivityProviderRegistry;
use Jiminny\Services\Import\ActivityImportManager;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class SyncActivity extends Job implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public const string ALLOWED_DATE_FORMAT = 'Y-m-d H:i:s';
public int $tries = 3;
public $queue = Constants::QUEUE_DIALERS;
private ActivityImport $import;
private ?ActivityImportManager $activityImportManager = null;
private ?UserRepository $userRepository = null;
private ?SentryClient $sentryClient = null;
private ?LoggerInterface $logger = null;
private ?Provider $provider = null;
private ?ImportsDataInterface $service = null;
private array $context;
public function __construct(ActivityImport $import)
{
$this->import = $import;
$this->context = ['import_id' => $import->getId()];
}
public function handle(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
try {
$this->init(
$activityImportManager,
$activityProviderRegistry,
$userRepository,
$sentry,
$logger,
);
} catch (Throwable $exception) {
$this->failImport($exception);
return;
}
Datadog::increment('jiminny.activity.sync.start', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
try {
$result = $this->run();
$this->complete($result);
} catch (Throwable $exception) {
$this->failImport($exception);
}
}
public function failed(Throwable $exception): void
{
$this->logger ??= app(LoggerInterface::class);
$this->activityImportManager ??= app(ActivityImportManager::class);
$this->sentryClient ??= app(SentryClient::class);
if (! isset($this->context)) {
// This can happen in case of improper deserialization.
$this->context = [];
}
$this->context['team'] ??= 'unknown';
$this->context['provider'] ??= 'unknown';
if (isset($this->import)) {
// This can happen in case of improper deserialization.
$this->failImport($exception);
}
}
/**
* @throws ActivityProviderException
* @throws SocialAccountTokenInvalidException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function init(
ActivityImportManager $activityImportManager,
ActivityProviderRegistry $activityProviderRegistry,
UserRepository $userRepository,
SentryClient $sentry,
LoggerInterface $logger,
): void {
$this->logger = $logger;
$this->activityImportManager = $activityImportManager;
$this->userRepository = $userRepository;
$this->sentryClient = $sentry;
$provider = $this->import->getActivityProvider();
$this->context['provider'] = $provider->getProviderSlug();
$this->context['provider_id'] = $provider->getId();
$this->context['team'] = $provider->getTeam()->getSlug();
$this->context['team_id'] = $provider->getTeamId();
if (! $provider->isEnabled()) {
throw new ActivityProviderException('Activity provider is disabled', $provider);
}
$this->provider = $provider;
$service = $activityProviderRegistry->get($provider->getProviderSlug());
if (! $service instanceof ImportsDataInterface) {
throw new ActivityProviderException('Activity provider does not support data imports', $provider);
}
$service->setTeam($provider->getTeam());
$service->setSocialAccount($provider->getConnectedSocialAccount());
$service->setDebug($this->import->runsInDebug());
$this->service = $service;
}
private function run(): ActivityImportResult
{
$this->logger->info('[SyncActivity] Start', $this->context);
$this->activityImportManager->start($this->import);
$importedRecords = $this->service->importData(
$this->import->getStartDate(),
$this->import->getEndDate(),
$this->userRepository->findOneBy(['id' => $this->import->getUserId()]),
$this->import->getActivityId()
);
return (new ActivityImportResult())
->setTotal($importedRecords)
->addImported($importedRecords)
;
}
private function complete(ActivityImportResult $result): void
{
$this->activityImportManager->complete($this->import, $result);
Datadog::increment('jiminny.activity.sync.success', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
]);
$this->logger->info('[SyncActivity] End', $this->context);
$this->logger->info(
'[SyncActivity] Memory usage',
array_merge(
$this->context,
[
'memory_usage' => memory_get_usage(),
'memory_real_usage' => memory_get_usage(true),
'pid' => getmypid(),
],
),
);
}
private function failImport(Throwable $exception): void
{
$this->logger->alert(
message: '[SyncActivity] Failed',
context: array_merge($this->context, [
'reason' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]),
);
$this->activityImportManager->fail($this->import);
Datadog::increment('jiminny.activity.sync.exception', 1.0, [
'company' => $this->context['team'],
'provider' => $this->context['provider'],
'exception' => $exception::class,
'exceptionCode' => $exception->getCode(),
]);
if ($exception instanceof SocialAccountTokenInvalidException) {
return;
}
$this->sentryClient->captureException($exception);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55337
|
1914
|
77
|
2026-05-18T14:02:37.557128+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112957557_m1.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Firefox• 0FileEditViewHistory→BookmarksProfilesToo Firefox• 0FileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kova100% <78 • Mon 18 May 17:02:37%40jiminny.comA05Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:49:04...
|
NULL
|
6082150210948719018
|
NULL
|
click
|
ocr
|
NULL
|
Firefox• 0FileEditViewHistory→BookmarksProfilesToo Firefox• 0FileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kova100% <78 • Mon 18 May 17:02:37%40jiminny.comA05Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:49:04...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55338
|
1914
|
78
|
2026-05-18T14:02:39.617387+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112959617_m1.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
People
5
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Pin Galya Dimitrova to your main screen
Mute Galya Dimitrova's microphone
More options for Galya Dimitrova
Galya Dimitrova
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
Mute Nikolay Ivanov's microphone
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08722222,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"5","depth":22,"bounds":{"left":0.9145833,"top":0.09888889,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08722222,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.09888889,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":17,"bounds":{"left":0.96666664,"top":0.09888889,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":17,"bounds":{"left":0.96458334,"top":0.08833333,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pin Galya Dimitrova to your main screen","depth":13,"bounds":{"left":0.26145834,"top":0.3122222,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Galya Dimitrova's microphone","depth":13,"bounds":{"left":0.2892361,"top":0.31,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Galya Dimitrova","depth":13,"bounds":{"left":0.31979167,"top":0.3122222,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Galya Dimitrova","depth":17,"bounds":{"left":0.10729167,"top":0.48277777,"width":0.08194444,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Yankov to your main screen","depth":13,"bounds":{"left":0.68645835,"top":0.3122222,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Nikolay Yankov's microphone","depth":13,"bounds":{"left":0.71423614,"top":0.31,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.7447917,"top":0.3122222,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.53229165,"top":0.48277777,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Ivanov to your main screen","depth":13,"bounds":{"left":0.15729167,"top":0.70111114,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Nikolay Ivanov's microphone","depth":13,"bounds":{"left":0.18506944,"top":0.6988889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Ivanov","depth":13,"bounds":{"left":0.215625,"top":0.70111114,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"bounds":{"left":0.057291668,"top":0.87166667,"width":0.07395833,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Aneliya Angelova to your main screen","depth":13,"bounds":{"left":0.47430557,"top":0.70111114,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.50208336,"top":0.6988889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Aneliya Angelova","depth":13,"bounds":{"left":0.5326389,"top":0.70111114,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"bounds":{"left":0.37395832,"top":0.87166667,"width":0.088541664,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"You’re continuously framed","depth":13,"bounds":{"left":0.7899306,"top":0.6988889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Backgrounds and effects","depth":13,"bounds":{"left":0.8204861,"top":0.6988889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-4557867572049390840
|
-258657383105340648
|
visual_change
|
hybrid
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
People
5
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Pin Galya Dimitrova to your main screen
Mute Galya Dimitrova's microphone
More options for Galya Dimitrova
Galya Dimitrova
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
Mute Nikolay Ivanov's microphone
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
Firefox•FileEditViewHistoryBookmarksProfiles→CToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com<100% [8• Mon 18 May 17:02:39=40 5+Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:49:06...
|
55337
|
NULL
|
NULL
|
NULL
|
|
55340
|
1915
|
36
|
2026-05-18T14:02:40.507404+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112960507_m2.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
People
5
Take notes with Gemini...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.69481385,"top":1.0,"width":0.019614361,"height":-0.06264961},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"5","depth":22,"bounds":{"left":0.7081117,"top":1.0,"width":0.0023271276,"height":-0.071029544},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.71708775,"top":1.0,"width":0.011968086,"height":-0.06264961},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1000802917541167286
|
4179417918253323910
|
click
|
hybrid
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
People
5
Take notes with Gemini
PnostormINavicatecodeFV faVsco.js v°9 master kroledey© ReindexForUserJob.phpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_ A kepors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.ondCalendarv 17Cmm> • Delete> M Hubsoot>D Salesforce(c) Autoloabelavedtocrm.nhnl(C) CheckAndRetrvRemoteMatch.nhnFindWiminny Services Activitv RinaCentral Service.imoortData in.X.v Method(m d importData service ...app/Services/Activity RinqCentral• Usages in Prolect Files 1 resulMethod call 1 resultvcaoo ] resulti~ Dapp/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul© BaseService.php© SoftPhoneManager.php© CoreUserRequest.phpscimProvistoning.ong© CoreUser.php© Activity/Close/service.php© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueorivatetunction runor ActivtvmoortResu.t$this->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO]),$this->import->getActivityId()recurn (new Accivicyimporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)1usageprivate function complete(ActivityImportResult $result): void=custom.logA console [STAGING]E laravel.log4 SF [jiminny@localhost]A HS_Jocal [jiminny@localhost]A console [PROD]A console (EU]© CoachingFeedbackCoachUserin.phpxfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini__construct(UserRepository $userRepository)(...}29 đt >34 đt >45 đt >118130136 Ct>public function shouldApplyQueries(): boolf..;public function getQueries(): FilterDefinitionQueryCollectionf...,public function toArray(): arrayf…..,private function getOptions(): arrayf..}public function getValue(): arrayf...,1 usageprivate function getDefaultValve(): arrayf...public function getValidationRules(?string $prefix = null): array(...}$service->setTeam($provider->getTeam());$service->setSocialAccount($provider->getConnectedSocialAccount());sservice->setdebua(sthis->imoort->runsindebugobs100% 5P• Mon 10 May 1/-02•34U AskJiminnyReportActivityServiceTestCascadeImplement Trial OwneFixing Redis Rate LimSalestorce Token FalliSCIM Role Manageme+0 ..Tnoughts• JiminnyDebugComr+40 -1Added a test action to the debug command. Run:php arcisan 11minny:debug reais-setThis will test the Redis SET operation with the fixed PhoRedis syntax ('EX', sttl. "NX') and verify it works with vourcurrent Redis client configuration.ФAsk anvthina (*4L1+ <>Code SWE-1.6private function runo: ActivitvimoortResultSthis->loagen->infor*|SvncActivitvl Starti Sthis->context)•$this-›activityImportManager->start(Sthis->import);$importedRecords = $this->service->importData(Sthis-simnont->aetStartDateor.lSthis->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])$this->import->getActivityId()return (new ActivityImportResult())->setTotal($importedRecords)->addImported($importedRecords)private function complete(ActivityImportResult $result): voiddehdr-ContiudtutanontMonaaor-tooanlhtoftthircdmnantdaoanltldCall Hierarchy165•661f 4 spaces...
|
55336
|
NULL
|
NULL
|
NULL
|
|
55339
|
1914
|
79
|
2026-05-18T14:02:40.533705+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112960533_m1.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
People
5
Take notes with Gemini...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08722222,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"5","depth":22,"bounds":{"left":0.9145833,"top":0.09888889,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08722222,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1000802917541167286
|
4179417918253323910
|
click
|
hybrid
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
People
5
Take notes with Gemini
FirefoxFileEdit→ViewHistoryBookmarksProfilesCToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com<100% <478• Mon 18 May 17:02:40=20 5Galya DimitrovaNikolay Yankov*4Nikolay IvanovAneliya AngelovaTurn on microphone (88 + d)Lukas Kovalik5:02 PM | [Platform] Refinement ®1:49:07...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55341
|
1914
|
80
|
2026-05-18T14:02:42.673285+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112962673_m1.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
7826844677319556675
|
7235299109264185591
|
visual_change
|
hybrid
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
F Meet - [Platform] Refinement 🔍
Close tab
New Tab
FirefoxFileEdit→ViewHistoryBookmarksProfilesCToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100%8• Mon 18 May 17:02:42=20 5Galya DimitrovaNikolay Yankov*4Nikolay IvanovAneliya AngelovaLukas Kovalik5:02 PM | [Platform] Refinement ®1:49:09...
|
55339
|
NULL
|
NULL
|
NULL
|
|
55343
|
1915
|
37
|
2026-05-18T14:02:47.139167+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112967139_m2.jpg...
|
CleanShot X
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PnostormINavicatecodeFV faVsco.js v°9 master krole PnostormINavicatecodeFV faVsco.js v°9 master kroledey© ReindexForUserJob.phpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_ A kepors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.ondCalendarv 17Cmm> • Delete> M Hubsoot>D Salesforce(c) Autoloabelavedtocrm.nhnl(C) CheckAndRetrvRemoteMatch.nhnFindWiminny Services Activitv RinaCentral Service.imoortData in.X.v Method(m d importData service ...app/Services/Activity RinqCentral• Usages in Prolect Files 1 resulMethod call 1 resultvcaoo ] resulti~ Dapp/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul© BaseService.php© SoftPhoneManager.php© CoreUserRequest.phpscimProvistoning.ong© CoreUser.php© Activity/Close/service.php© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueorivatetunction runor ActivtvmoortResu.t$this->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO]),$this->import->getActivityId()recurn (new Accivicyimporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)1usageprivate function complete(ActivityImportResult $result): void=custom.logA console [STAGING]E laravel.log4 SF [jiminny@localhost]A HS_Jocal [jiminny@localhost]A console [PROD]A console (EU]© CoachingFeedbackCoachUserin.phpxfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini__construct(UserRepository $userRepository)(...}29 đt >34 đt >45 đt >118130136 Ct>public function shouldApplyQueries(): boolf..;public function getQueries(): FilterDefinitionQueryCollectionf...,public function toArray(): arrayf…..,private function getOptions(): arrayf..}public function getValue(): arrayf...,1 usageprivate function getDefaultValve(): arrayf...public function getValidationRules(?string $prefix = null): array(...}$service->setTeam($provider->getTeam());$service->setSocialAccount($provider->getConnectedSocialAccount());sservice->setdebua(sthis->imoort->runsindebugobs100% 5P• мon 10 May 1/-02.40U AskJiminnyReportActivityServiceTestCascadeImplement Trial OwneFixing Redis Rate LimSalestorce Token FalliSCIM Role Manageme+0 ..Tnoughts• JiminnyDebugComr+40 -1Added a test action to the debug command. Run:php arcisan 11minny:debug reais-setThis will test the Redis SET operation with the fixed PhoRedis syntax ('EX', sttl. "NX') and verify it works with vourcurrent Redis client configuration.ФAsk anvthina (*4L1+ <>Code SWE-1.6private function runo: ActivitvimoortResultSthis->loagen->infor*|SvncActivitvl Starti Sthis->context)•$this-›activityImportManager->start(Sthis->import);$importedRecords = $this->service->importData(Sthis-simnont->aetStartDateor.lSthis->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])$this->import->getActivityId()return (new ActivityImportResult())->setTotal($importedRecords)->addImported($importedRecords)private function complete(ActivityImportResult $result): voiddehdr-ContiudtutanontMonaaor-tooanlhtoftthircdmnantdaoanltldCall Hierarchy165•661f 4 spaces...
|
NULL
|
115422498146671083
|
NULL
|
click
|
ocr
|
NULL
|
PnostormINavicatecodeFV faVsco.js v°9 master krole PnostormINavicatecodeFV faVsco.js v°9 master kroledey© ReindexForUserJob.phpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_ A kepors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.ondCalendarv 17Cmm> • Delete> M Hubsoot>D Salesforce(c) Autoloabelavedtocrm.nhnl(C) CheckAndRetrvRemoteMatch.nhnFindWiminny Services Activitv RinaCentral Service.imoortData in.X.v Method(m d importData service ...app/Services/Activity RinqCentral• Usages in Prolect Files 1 resulMethod call 1 resultvcaoo ] resulti~ Dapp/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul© BaseService.php© SoftPhoneManager.php© CoreUserRequest.phpscimProvistoning.ong© CoreUser.php© Activity/Close/service.php© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueorivatetunction runor ActivtvmoortResu.t$this->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO]),$this->import->getActivityId()recurn (new Accivicyimporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)1usageprivate function complete(ActivityImportResult $result): void=custom.logA console [STAGING]E laravel.log4 SF [jiminny@localhost]A HS_Jocal [jiminny@localhost]A console [PROD]A console (EU]© CoachingFeedbackCoachUserin.phpxfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini__construct(UserRepository $userRepository)(...}29 đt >34 đt >45 đt >118130136 Ct>public function shouldApplyQueries(): boolf..;public function getQueries(): FilterDefinitionQueryCollectionf...,public function toArray(): arrayf…..,private function getOptions(): arrayf..}public function getValue(): arrayf...,1 usageprivate function getDefaultValve(): arrayf...public function getValidationRules(?string $prefix = null): array(...}$service->setTeam($provider->getTeam());$service->setSocialAccount($provider->getConnectedSocialAccount());sservice->setdebua(sthis->imoort->runsindebugobs100% 5P• мon 10 May 1/-02.40U AskJiminnyReportActivityServiceTestCascadeImplement Trial OwneFixing Redis Rate LimSalestorce Token FalliSCIM Role Manageme+0 ..Tnoughts• JiminnyDebugComr+40 -1Added a test action to the debug command. Run:php arcisan 11minny:debug reais-setThis will test the Redis SET operation with the fixed PhoRedis syntax ('EX', sttl. "NX') and verify it works with vourcurrent Redis client configuration.ФAsk anvthina (*4L1+ <>Code SWE-1.6private function runo: ActivitvimoortResultSthis->loagen->infor*|SvncActivitvl Starti Sthis->context)•$this-›activityImportManager->start(Sthis->import);$importedRecords = $this->service->importData(Sthis-simnont->aetStartDateor.lSthis->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])$this->import->getActivityId()return (new ActivityImportResult())->setTotal($importedRecords)->addImported($importedRecords)private function complete(ActivityImportResult $result): voiddehdr-ContiudtutanontMonaaor-tooanlhtoftthircdmnantdaoanltldCall Hierarchy165•661f 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55342
|
1914
|
81
|
2026-05-18T14:02:47.203531+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112967203_m1.jpg...
|
CleanShot X
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
1:49:14
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"1:49:14","depth":1,"bounds":{"left":0.74409723,"top":0.9494445,"width":0.036111113,"height":0.015555556},"on_screen":true,"role_description":"text"}]...
|
7791357114204056524
|
7791357114204056524
|
click
|
hybrid
|
NULL
|
1:49:14
Firefox•FileEditViewHistoryBookmarksProfil 1:49:14
Firefox•FileEditViewHistoryBookmarksProfiles→CToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100%8• Mon 18 May 17:02:46=A05Galya DimitrovaNikolay Yankov*4Nikolay IvanovAneliya AngelovaLukas Kovalik.Leave call5:02 PM | [Platform] Refinement ®1:49:14...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55344
|
1914
|
82
|
2026-05-18T14:02:48.749924+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112968749_m1.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
8992942050729142726
|
8964681366242680919
|
visual_change
|
hybrid
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
+FirefoxF Meet - [Platform] Refinement 🔍
Close tab
+FirefoxFileEditViewHistoryBookmarksProfiles→CToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% C8 • Mon 18 May 17:02:48A05Galya DimitrovaNikolay Yankov*4109R Jlay Ivafi856BAneliya AngelovaLukas KovalikLeave call5:02 PM | [Platform] Refinement ®...
|
55342
|
NULL
|
NULL
|
NULL
|
|
55346
|
1915
|
38
|
2026-05-18T14:02:50.491349+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112970491_m2.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true}]...
|
-200939925990973835
|
-260678276249952170
|
click
|
hybrid
|
NULL
|
Meet - [Platform] Refinement 🔍
PnostormINavicateco Meet - [Platform] Refinement 🔍
PnostormINavicatecodeFV faVsco.js v°9 master kroledey© ReindexForUserJob.phpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_ A kepors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.ondCalendarv 17Cmm> • Delete> M Hubsoot>D Salesforce(c) Autoloabelavedtocrm.nhnl(C) CheckAndRetrvRemoteMatch.nhnFindWiminny Services Activitv RinaCentral Service.imoortData in.X.v Method(m d importData service ...app/Services/Activity RinqCentral• Usages in Prolect Files 1 resulMethod call 1 resultvcaoo ] resulti~ Dapp/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul© BaseService.php© SoftPhoneManager.php© CoreUserRequest.phpscimProvistoning.ong© CoreUser.php© Activity/Close/service.php© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueorivatetunction runor ActivtvmoortResu.t$this->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO]),$this->import->getActivityId()recurn (new Accivicyimporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)1usage=custom.logA console [STAGING]E laravel.log4 SF [jiminny@localhost]A HS_Jocal [jiminny@localhost]A console [PROD]A console (EU]© CoachingFeedbackCoachUserin.phpxfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini__construct(UserRepository $userRepository)(...}29 đt >34 đt >45 đt >118130136 Ct>public function shouldApplyQueries(): boolf..;public function getQueries(): FilterDefinitionQueryCollectionf...,public function toArray(): arrayf…..,private function getOptions(): arrayf..}public function getValue(): arrayf...,1 usageprivate function getDefaultValve(): arrayf...public function getValidationRules(?string $prefix = null): array(...}A1. Yprivate function complete(ActivityImportResult $result): void100% 5P• Mon 10 May 1/-U2-00U AskJiminnyReportActivityServiceTestCascadeImplement Trial OwneFixing Redis Rate LimSalestorce Token FalliSCIM Role Manageme+0 ..Tnoughts• JiminnyDebugComr+40 -1Added a test action to the debug command. Run:php arcisan 11minny:debug reais-setThis will test the Redis SET operation with the fixed PhoRedis syntax ('EX', sttl. "NX') and verify it works with vourcurrent Redis client configuration.ФAsk anvthina (*4L1+ <>Code SWE-1.6$service->setTeam($provider->getTeam());$service->setSocialAccount($provider->getConnectedSocialAccount());sservice->setdebua(sthis->imoort->runsindebugobsprivate function runo: ActivitvimoortResultSthis->loagen->infor*|SvncActivitvl Starti Sthis->context)•$this-›activityImportManager->start(Sthis->import);$importedRecords = $this->service->importData(Sthis-simnont->aetStartDateor.lSthis->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])$this->import->getActivityId()return (new ActivityImportResult())->setTotal($importedRecords)->addImported($importedRecords)private function complete(ActivityImportResult $result): voiddehdr-ContiudtutanontMonaaor-tooanlhtoftthircdmnantdaoanltldCall Hierarchy165•661f 4 spaces...
|
55343
|
NULL
|
NULL
|
NULL
|
|
55345
|
1914
|
83
|
2026-05-18T14:02:51.771669+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112971771_m1.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You left the meeting","depth":10,"bounds":{"left":0.4045139,"top":0.18333334,"width":0.22465278,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You left the meeting","depth":11,"bounds":{"left":0.4045139,"top":0.18277778,"width":0.22465278,"height":0.050555557},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rejoin","depth":11,"bounds":{"left":0.41493055,"top":0.27222222,"width":0.062152777,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Rejoin","depth":13,"bounds":{"left":0.43229166,"top":0.28444445,"width":0.027430555,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Return to home screen","depth":11,"bounds":{"left":0.4826389,"top":0.27222222,"width":0.13611111,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Return to home screen","depth":13,"bounds":{"left":0.49930555,"top":0.28444445,"width":0.10277778,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"How was the audio and video?","depth":10,"bounds":{"left":0.41284722,"top":0.39222223,"width":0.20833333,"height":0.046666667},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How was the audio and video?","depth":11,"bounds":{"left":0.41284722,"top":0.39444444,"width":0.15729167,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Rate the meeting 1 star out of 5.","depth":10,"bounds":{"left":0.41631943,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 2 stars out of 5.","depth":10,"bounds":{"left":0.45833334,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
8315589632021635533
|
-2875514877473915262
|
visual_change
|
accessibility
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5....
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55348
|
1915
|
39
|
2026-05-18T14:02:53.285732+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112973285_m2.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5.
Rate the meeting 3 stars out of 5.
Rate the meeting 4 stars out of 5.
Rate the meeting 5 stars out of 5.
Very bad
Very good
Feedback
Feedback
59
Returning to home screen
Returning to home screen in 60 seconds.
Background is no longer replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You left the meeting","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You left the meeting","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rejoin","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Rejoin","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Return to home screen","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Return to home screen","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"How was the audio and video?","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How was the audio and video?","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Rate the meeting 1 star out of 5.","depth":10,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 2 stars out of 5.","depth":10,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 3 stars out of 5.","depth":10,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 4 stars out of 5.","depth":10,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 5 stars out of 5.","depth":10,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Very bad","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Very good","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Feedback","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feedback","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"59","depth":12,"bounds":{"left":0.2997008,"top":1.0,"width":0.005319149,"height":-0.083798885},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Returning to home screen","depth":12,"bounds":{"left":0.31432846,"top":1.0,"width":0.0546875,"height":-0.083798885},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Returning to home screen in 60 seconds.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is no longer replaced","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
1916865751001783241
|
5316528175011113602
|
click
|
accessibility
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5.
Rate the meeting 3 stars out of 5.
Rate the meeting 4 stars out of 5.
Rate the meeting 5 stars out of 5.
Very bad
Very good
Feedback
Feedback
59
Returning to home screen
Returning to home screen in 60 seconds.
Background is no longer replaced...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55347
|
1914
|
84
|
2026-05-18T14:02:53.306780+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112973306_m1.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5.
Rate the meeting 3 stars out of 5.
Rate the meeting 4 stars out of 5.
Rate the meeting 5 stars out of 5.
Very bad
Very good
Feedback
Feedback
59
Returning to home screen
Returning to home screen in 60 seconds.
Background is no longer replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You left the meeting","depth":10,"bounds":{"left":0.4045139,"top":0.18333334,"width":0.22465278,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You left the meeting","depth":11,"bounds":{"left":0.4045139,"top":0.18277778,"width":0.22465278,"height":0.050555557},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rejoin","depth":11,"bounds":{"left":0.41493055,"top":0.27222222,"width":0.062152777,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Rejoin","depth":13,"bounds":{"left":0.43229166,"top":0.28444445,"width":0.027430555,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Return to home screen","depth":11,"bounds":{"left":0.4826389,"top":0.27222222,"width":0.13611111,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Return to home screen","depth":13,"bounds":{"left":0.49930555,"top":0.28444445,"width":0.10277778,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"How was the audio and video?","depth":10,"bounds":{"left":0.41284722,"top":0.39222223,"width":0.20833333,"height":0.046666667},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How was the audio and video?","depth":11,"bounds":{"left":0.41284722,"top":0.39444444,"width":0.15729167,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Rate the meeting 1 star out of 5.","depth":10,"bounds":{"left":0.41631943,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 2 stars out of 5.","depth":10,"bounds":{"left":0.45833334,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 3 stars out of 5.","depth":10,"bounds":{"left":0.5003472,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 4 stars out of 5.","depth":10,"bounds":{"left":0.54236114,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 5 stars out of 5.","depth":10,"bounds":{"left":0.584375,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Very bad","depth":11,"bounds":{"left":0.41979167,"top":0.49333334,"width":0.034027778,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Very good","depth":11,"bounds":{"left":0.575,"top":0.49333334,"width":0.03923611,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Feedback","depth":11,"bounds":{"left":0.03784722,"top":0.95111114,"width":0.081597224,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feedback","depth":13,"bounds":{"left":0.06423611,"top":0.9633333,"width":0.044097222,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"59","depth":12,"bounds":{"left":0.061458334,"top":0.11666667,"width":0.011111111,"height":0.018333333},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Returning to home screen","depth":12,"bounds":{"left":0.09201389,"top":0.11666667,"width":0.11423611,"height":0.018333333},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Returning to home screen in 60 seconds.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is no longer replaced","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
1916865751001783241
|
5316528175011113602
|
click
|
accessibility
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5.
Rate the meeting 3 stars out of 5.
Rate the meeting 4 stars out of 5.
Rate the meeting 5 stars out of 5.
Very bad
Very good
Feedback
Feedback
59
Returning to home screen
Returning to home screen in 60 seconds.
Background is no longer replaced...
|
55345
|
NULL
|
NULL
|
NULL
|
|
55349
|
1914
|
85
|
2026-05-18T14:02:54.827740+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112974827_m1.jpg...
|
Firefox
|
Meet - [Platform] Refinement 🔍 — Work
|
1
|
meet.google.com/cxs-eips-npt?authuser=lukas.kovali meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5.
Rate the meeting 3 stars out of 5.
Rate the meeting 4 stars out of 5.
Rate the meeting 5 stars out of 5.
Very bad
Very good
Feedback
Feedback
57
Returning to home screen
Returning to home screen in 60 seconds.
Background is no longer replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - [Platform] Refinement 🔍","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You left the meeting","depth":10,"bounds":{"left":0.4045139,"top":0.18333334,"width":0.22465278,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You left the meeting","depth":11,"bounds":{"left":0.4045139,"top":0.18277778,"width":0.22465278,"height":0.050555557},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rejoin","depth":11,"bounds":{"left":0.41493055,"top":0.27222222,"width":0.062152777,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Rejoin","depth":13,"bounds":{"left":0.43229166,"top":0.28444445,"width":0.027430555,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Return to home screen","depth":11,"bounds":{"left":0.4826389,"top":0.27222222,"width":0.13611111,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Return to home screen","depth":13,"bounds":{"left":0.49930555,"top":0.28444445,"width":0.10277778,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"How was the audio and video?","depth":10,"bounds":{"left":0.41284722,"top":0.39222223,"width":0.20833333,"height":0.046666667},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How was the audio and video?","depth":11,"bounds":{"left":0.41284722,"top":0.39444444,"width":0.15729167,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Rate the meeting 1 star out of 5.","depth":10,"bounds":{"left":0.41631943,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 2 stars out of 5.","depth":10,"bounds":{"left":0.45833334,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 3 stars out of 5.","depth":10,"bounds":{"left":0.5003472,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 4 stars out of 5.","depth":10,"bounds":{"left":0.54236114,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Rate the meeting 5 stars out of 5.","depth":10,"bounds":{"left":0.584375,"top":0.43888888,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Very bad","depth":11,"bounds":{"left":0.41979167,"top":0.49333334,"width":0.034027778,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Very good","depth":11,"bounds":{"left":0.575,"top":0.49333334,"width":0.03923611,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Feedback","depth":11,"bounds":{"left":0.03784722,"top":0.95111114,"width":0.081597224,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feedback","depth":13,"bounds":{"left":0.06423611,"top":0.9633333,"width":0.044097222,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"57","depth":12,"bounds":{"left":0.061458334,"top":0.11666667,"width":0.011111111,"height":0.018333333},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Returning to home screen","depth":12,"bounds":{"left":0.09201389,"top":0.11666667,"width":0.11423611,"height":0.018333333},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Returning to home screen in 60 seconds.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is no longer replaced","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-2647872528003589944
|
5316528175009017506
|
visual_change
|
accessibility
|
NULL
|
Meet - [Platform] Refinement 🔍
Close tab
New Tab
O Meet - [Platform] Refinement 🔍
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
You left the meeting
You left the meeting
Rejoin
Rejoin
Return to home screen
Return to home screen
How was the audio and video?
How was the audio and video?
Rate the meeting 1 star out of 5.
Rate the meeting 2 stars out of 5.
Rate the meeting 3 stars out of 5.
Rate the meeting 4 stars out of 5.
Rate the meeting 5 stars out of 5.
Very bad
Very good
Feedback
Feedback
57
Returning to home screen
Returning to home screen in 60 seconds.
Background is no longer replaced...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55350
|
NULL
|
0
|
2026-05-18T14:02:57.845267+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112977845_m1.jpg...
|
Finder
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Finder File•<→ CEdit View GoWindowHelp100% C47 Finder File•<→ CEdit View GoWindowHelp100% C47 8• Mon 18 May 17:02:57• =@ meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com(55)Returning to home screenYou left the meetingRejoinReturn to home screenHow was the audio and video?Very badVery good• Feedback...
|
NULL
|
2252365249669368265
|
NULL
|
visual_change
|
ocr
|
NULL
|
Finder File•<→ CEdit View GoWindowHelp100% C47 Finder File•<→ CEdit View GoWindowHelp100% C47 8• Mon 18 May 17:02:57• =@ meet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com(55)Returning to home screenYou left the meetingRejoinReturn to home screenHow was the audio and video?Very badVery good• Feedback...
|
55349
|
NULL
|
NULL
|
NULL
|
|
55351
|
1915
|
40
|
2026-05-18T14:02:58.170480+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112978170_m2.jpg...
|
Finder
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
WinaowFV faVsco.js°9 master kProletey©) ReindexFor WinaowFV faVsco.js°9 master kProletey©) ReindexForUserJob.pnpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_ A kepors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.onvCalendarv 17Cmm› M Delete> M Hubsoot1631> IM Salesforce(c) Autoloabelavedtocrm.nhnl(C) CheckAndRetrvRemoteMatch.nhnFindWiminny) Services Activitv RinaCentral Service.imoortData in.. X.• Mothadl(m d importData service ...app/services/Activity RinaCentra• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resultiv D app/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul© SoftPhoneManager.php(C) CoreUserRequest.onpscimProvistoning.ong© CoreUser.php© Activity/Close/service.pnp© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mpLements Shouldoueueorivatetunction runor ActivtvmoortResult$this->import->getEndDateO$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])Sthis->import->getActivityIdOrecurn (new Acciv1cylmporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)= custom.log= laravel.logA console [STAGING]© Coachtinal class coaching29 đ >34 0 >45 gt118119131136 @>public function slpubuic tunction glpublic function ti1 usageprivate functionpublac function q1lusadeorivate Functionpublic function gprivate function complete(ActivityImportResult $result): void•• cFavourites• jiminny(®) AirDrop• RecentsA Applications|9 Documents• Downloadsn lukasiCloud• iCloud Drive992 Svnc tolderLocations• DXP4800PLUS-B5F|49 Network• CRMI• Orange• Red• Yellow• Greero Bue• Purple• All Tags..F1 109m 14cl405 GR100% L2?• Mon 18 May 17:02:58Lukas Kovalik's macbook Pro JiminnyQ Search^ Date Modified4 Aug 2024 at 13:31>• Macintosh HD> € Network215 99 Cp Ctartun Volumo...
|
NULL
|
-6000358215392795091
|
NULL
|
click
|
ocr
|
NULL
|
WinaowFV faVsco.js°9 master kProletey©) ReindexFor WinaowFV faVsco.js°9 master kProletey©) ReindexForUserJob.pnpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_ A kepors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.onvCalendarv 17Cmm› M Delete> M Hubsoot1631> IM Salesforce(c) Autoloabelavedtocrm.nhnl(C) CheckAndRetrvRemoteMatch.nhnFindWiminny) Services Activitv RinaCentral Service.imoortData in.. X.• Mothadl(m d importData service ...app/services/Activity RinaCentra• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resultiv D app/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul© SoftPhoneManager.php(C) CoreUserRequest.onpscimProvistoning.ong© CoreUser.php© Activity/Close/service.pnp© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mpLements Shouldoueueorivatetunction runor ActivtvmoortResult$this->import->getEndDateO$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])Sthis->import->getActivityIdOrecurn (new Acciv1cylmporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)= custom.log= laravel.logA console [STAGING]© Coachtinal class coaching29 đ >34 0 >45 gt118119131136 @>public function slpubuic tunction glpublic function ti1 usageprivate functionpublac function q1lusadeorivate Functionpublic function gprivate function complete(ActivityImportResult $result): void•• cFavourites• jiminny(®) AirDrop• RecentsA Applications|9 Documents• Downloadsn lukasiCloud• iCloud Drive992 Svnc tolderLocations• DXP4800PLUS-B5F|49 Network• CRMI• Orange• Red• Yellow• Greero Bue• Purple• All Tags..F1 109m 14cl405 GR100% L2?• Mon 18 May 17:02:58Lukas Kovalik's macbook Pro JiminnyQ Search^ Date Modified4 Aug 2024 at 13:31>• Macintosh HD> € Network215 99 Cp Ctartun Volumo...
|
55348
|
NULL
|
NULL
|
NULL
|
|
55352
|
NULL
|
0
|
2026-05-18T14:02:59.496729+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112979496_m2.jpg...
|
Finder
|
DXP4800PLUS-B5F
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
Name
Date Modified
Size
Kind
Connecting…
Connect As…
0 items
DXP4800PLUS-B5F...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Favourites","depth":6,"bounds":{"left":0.5046542,"top":0.061452515,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"jiminny","depth":6,"bounds":{"left":0.51263297,"top":0.08140463,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AirDrop","depth":6,"bounds":{"left":0.51263297,"top":0.103751,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Recents","depth":6,"bounds":{"left":0.51263297,"top":0.12609737,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Applications","depth":6,"bounds":{"left":0.51263297,"top":0.14844373,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Documents","depth":6,"bounds":{"left":0.51263297,"top":0.1707901,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Downloads","depth":6,"bounds":{"left":0.51263297,"top":0.19313647,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lukas","depth":6,"bounds":{"left":0.51263297,"top":0.21548285,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"iCloud","depth":6,"bounds":{"left":0.5046542,"top":0.2434158,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"iCloud Drive","depth":6,"bounds":{"left":0.51263297,"top":0.26336792,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sync folder","depth":6,"bounds":{"left":0.51263297,"top":0.2857143,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locations","depth":6,"bounds":{"left":0.5046542,"top":0.31364724,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":6,"bounds":{"left":0.51263297,"top":0.33359936,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Network","depth":6,"bounds":{"left":0.51263297,"top":0.35594574,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tags","depth":6,"bounds":{"left":0.5046542,"top":0.38387868,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"CRM","depth":6,"bounds":{"left":0.51263297,"top":0.4038308,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Orange","depth":6,"bounds":{"left":0.51263297,"top":0.42617717,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Red","depth":6,"bounds":{"left":0.51263297,"top":0.44852355,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yellow","depth":6,"bounds":{"left":0.51263297,"top":0.4708699,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Green","depth":6,"bounds":{"left":0.51263297,"top":0.49321628,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blue","depth":6,"bounds":{"left":0.51263297,"top":0.51556265,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Purple","depth":6,"bounds":{"left":0.51263297,"top":0.53790903,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"All Tags…","depth":6,"bounds":{"left":0.51263297,"top":0.5602554,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Name","depth":7,"bounds":{"left":0.5827792,"top":0.08858739,"width":0.011968086,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Date Modified","depth":7,"bounds":{"left":0.8656915,"top":0.08858739,"width":0.025930852,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Size","depth":7,"bounds":{"left":0.92586434,"top":0.08858739,"width":0.008976064,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Kind","depth":7,"bounds":{"left":0.9581117,"top":0.08858739,"width":0.00930851,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Name","depth":6,"bounds":{"left":0.5711436,"top":0.083798885,"width":0.29288563,"height":0.022346368},"on_screen":true,"role_description":"sort button","subrole":"AXSortButton","is_enabled":true,"is_focused":false},{"role":"AXButton","text":"Date Modified","depth":6,"bounds":{"left":0.8640292,"top":0.083798885,"width":0.06017287,"height":0.022346368},"on_screen":true,"role_description":"sort button","subrole":"AXSortButton","is_enabled":true,"is_focused":false},{"role":"AXButton","text":"Size","depth":6,"bounds":{"left":0.92420214,"top":0.083798885,"width":0.032247342,"height":0.022346368},"on_screen":true,"role_description":"sort button","subrole":"AXSortButton","is_enabled":true,"is_focused":false},{"role":"AXButton","text":"Kind","depth":6,"bounds":{"left":0.95644945,"top":0.083798885,"width":0.040226065,"height":0.022346368},"on_screen":true,"role_description":"sort button","subrole":"AXSortButton","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"Connecting…","depth":2,"bounds":{"left":0.57081115,"top":0.06624102,"width":0.02825798,"height":0.011971269},"on_screen":true,"automation_id":"_NS:10","role_description":"text"},{"role":"AXButton","text":"Connect As…","depth":2,"bounds":{"left":0.9684175,"top":0.065442935,"width":0.027925532,"height":0.015163607},"on_screen":true,"automation_id":"_NS:38","role_description":"button","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"0 items","depth":2,"bounds":{"left":0.77360374,"top":0.98324025,"width":0.016954787,"height":0.011173184},"on_screen":true,"automation_id":"_NS:34","role_description":"text"},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":1,"bounds":{"left":0.5990692,"top":0.019952115,"width":0.14378324,"height":0.0415004},"on_screen":true,"role_description":"text"}]...
|
-5489754960907684982
|
-1839682751017496682
|
visual_change
|
accessibility
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
Name
Date Modified
Size
Kind
Connecting…
Connect As…
0 items
DXP4800PLUS-B5F...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55353
|
1916
|
0
|
2026-05-18T14:03:28.337709+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113008337_m1.jpg...
|
Finder
|
DXP4800PLUS-B5F
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
Hide
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
Youtube
--
--
Sharepoint
Work
--
--
Sharepoint
Test
--
--
Sharepoint
screenpipe
--
--
Sharepoint
personal_folder
--
--
Sharepoint
Music
--
--
Sharepoint
Movies
--
--
Sharepoint
Media
--
--
Sharepoint
Marti
--
--
Sharepoint
Google
--
--
Sharepoint
games
--
--
Sharepoint
Family tree documents
--
--
Sharepoint
EFI
--...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Favourites","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"jiminny","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AirDrop","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Recents","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Applications","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Documents","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Downloads","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lukas","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"iCloud","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"iCloud Drive","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sync folder","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locations","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXDisclosureTriangle","text":"Hide","depth":6,"on_screen":true,"automation_id":"NSOutlineViewShowHideButtonKey","role_description":"disclosure triangle","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Network","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tags","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"CRM","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Orange","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Red","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yellow","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Green","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blue","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Purple","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"All Tags…","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Name","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Date Modified","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Size","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Kind","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Youtube","depth":7,"on_screen":true,"value":"Youtube","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Work","depth":7,"on_screen":true,"value":"Work","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Test","depth":7,"on_screen":true,"value":"Test","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"screenpipe","depth":7,"on_screen":true,"value":"screenpipe","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"personal_folder","depth":7,"on_screen":true,"value":"personal_folder","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Music","depth":7,"on_screen":true,"value":"Music","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Movies","depth":7,"on_screen":true,"value":"Movies","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Media","depth":7,"on_screen":true,"value":"Media","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Marti","depth":7,"on_screen":true,"value":"Marti","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Google","depth":7,"on_screen":true,"value":"Google","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"games","depth":7,"on_screen":true,"value":"games","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Family tree documents","depth":7,"on_screen":true,"value":"Family tree documents","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"EFI","depth":7,"on_screen":true,"value":"EFI","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"on_screen":true,"role_description":"text"}]...
|
-1460346899707314141
|
-5433415238070649113
|
idle
|
accessibility
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
Hide
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
Youtube
--
--
Sharepoint
Work
--
--
Sharepoint
Test
--
--
Sharepoint
screenpipe
--
--
Sharepoint
personal_folder
--
--
Sharepoint
Music
--
--
Sharepoint
Movies
--
--
Sharepoint
Media
--
--
Sharepoint
Marti
--
--
Sharepoint
Google
--
--
Sharepoint
games
--
--
Sharepoint
Family tree documents
--
--
Sharepoint
EFI
--...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55354
|
1917
|
0
|
2026-05-18T14:03:29.759484+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113009759_m2.jpg...
|
Finder
|
DXP4800PLUS-B5F
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
Hide
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
Youtube
--
--
Sharepoint
Work
--
--
Sharepoint
Test
--
--
Sharepoint
screenpipe
--
--
Sharepoint
personal_folder
--
--
Sharepoint
Music
--
--
Sharepoint
Movies
--
--
Sharepoint
Media
--
--
Sharepoint
Marti
--
--
Sharepoint
Google
--
--
Sharepoint
games
--
--
Sharepoint
Family tree documents
--
--
Sharepoint
EFI
--
--
Sharepoint
ebooks
--
--
Sharepoint
Documents...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Favourites","depth":6,"bounds":{"left":0.5046542,"top":0.061452515,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"jiminny","depth":6,"bounds":{"left":0.51263297,"top":0.08140463,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AirDrop","depth":6,"bounds":{"left":0.51263297,"top":0.103751,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Recents","depth":6,"bounds":{"left":0.51263297,"top":0.12609737,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Applications","depth":6,"bounds":{"left":0.51263297,"top":0.14844373,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Documents","depth":6,"bounds":{"left":0.51263297,"top":0.1707901,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Downloads","depth":6,"bounds":{"left":0.51263297,"top":0.19313647,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lukas","depth":6,"bounds":{"left":0.51263297,"top":0.21548285,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"iCloud","depth":6,"bounds":{"left":0.5046542,"top":0.2434158,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"iCloud Drive","depth":6,"bounds":{"left":0.51263297,"top":0.26336792,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sync folder","depth":6,"bounds":{"left":0.51263297,"top":0.2857143,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locations","depth":6,"bounds":{"left":0.5046542,"top":0.31364724,"width":0.054521278,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXDisclosureTriangle","text":"Hide","depth":6,"bounds":{"left":0.55917555,"top":0.31364724,"width":0.004986702,"height":0.015163607},"on_screen":true,"automation_id":"NSOutlineViewShowHideButtonKey","role_description":"disclosure triangle","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":6,"bounds":{"left":0.51263297,"top":0.33359936,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Network","depth":6,"bounds":{"left":0.51263297,"top":0.35594574,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tags","depth":6,"bounds":{"left":0.5046542,"top":0.38387868,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"CRM","depth":6,"bounds":{"left":0.51263297,"top":0.4038308,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Orange","depth":6,"bounds":{"left":0.51263297,"top":0.42617717,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Red","depth":6,"bounds":{"left":0.51263297,"top":0.44852355,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yellow","depth":6,"bounds":{"left":0.51263297,"top":0.4708699,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Green","depth":6,"bounds":{"left":0.51263297,"top":0.49321628,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blue","depth":6,"bounds":{"left":0.51263297,"top":0.51556265,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Purple","depth":6,"bounds":{"left":0.51263297,"top":0.53790903,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"All Tags…","depth":6,"bounds":{"left":0.51263297,"top":0.5602554,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Name","depth":7,"bounds":{"left":0.5827792,"top":0.08858739,"width":0.011968086,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Date Modified","depth":7,"bounds":{"left":0.8656915,"top":0.08858739,"width":0.025930852,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Size","depth":7,"bounds":{"left":0.92586434,"top":0.08858739,"width":0.008976064,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Kind","depth":7,"bounds":{"left":0.9581117,"top":0.08858739,"width":0.00930851,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Youtube","depth":7,"bounds":{"left":0.5827792,"top":0.11173184,"width":0.019281914,"height":0.012769354},"on_screen":true,"value":"Youtube","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.11173184,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.11173184,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.11173184,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Work","depth":7,"bounds":{"left":0.5827792,"top":0.12769353,"width":0.013297873,"height":0.012769354},"on_screen":true,"value":"Work","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.12769353,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.12769353,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.12769353,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Test","depth":7,"bounds":{"left":0.5827792,"top":0.14365523,"width":0.011303191,"height":0.012769354},"on_screen":true,"value":"Test","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.14365523,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.14365523,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.14365523,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"screenpipe","depth":7,"bounds":{"left":0.5827792,"top":0.15961692,"width":0.025265958,"height":0.012769354},"on_screen":true,"value":"screenpipe","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.15961692,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.15961692,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.15961692,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"personal_folder","depth":7,"bounds":{"left":0.5827792,"top":0.17557861,"width":0.034242023,"height":0.012769354},"on_screen":true,"value":"personal_folder","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.17557861,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.17557861,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.17557861,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Music","depth":7,"bounds":{"left":0.5827792,"top":0.1915403,"width":0.01462766,"height":0.012769354},"on_screen":true,"value":"Music","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.1915403,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.1915403,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.1915403,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Movies","depth":7,"bounds":{"left":0.5827792,"top":0.207502,"width":0.016954787,"height":0.012769354},"on_screen":true,"value":"Movies","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.207502,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.207502,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.207502,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Media","depth":7,"bounds":{"left":0.5827792,"top":0.22346368,"width":0.014960106,"height":0.012769354},"on_screen":true,"value":"Media","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.22346368,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.22346368,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.22346368,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Marti","depth":7,"bounds":{"left":0.5827792,"top":0.23942538,"width":0.013297873,"height":0.012769354},"on_screen":true,"value":"Marti","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.23942538,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.23942538,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.23942538,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Google","depth":7,"bounds":{"left":0.5827792,"top":0.25538707,"width":0.017287234,"height":0.012769354},"on_screen":true,"value":"Google","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.25538707,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.25538707,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.25538707,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"games","depth":7,"bounds":{"left":0.5827792,"top":0.27134877,"width":0.016289894,"height":0.012769354},"on_screen":true,"value":"games","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.27134877,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.27134877,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.27134877,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Family tree documents","depth":7,"bounds":{"left":0.5827792,"top":0.28731045,"width":0.048537236,"height":0.012769354},"on_screen":true,"value":"Family tree documents","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.28731045,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.28731045,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.28731045,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"EFI","depth":7,"bounds":{"left":0.5827792,"top":0.30327216,"width":0.008976064,"height":0.012769354},"on_screen":true,"value":"EFI","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.30327216,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.30327216,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.30327216,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"ebooks","depth":7,"bounds":{"left":0.5827792,"top":0.31923383,"width":0.017287234,"height":0.012769354},"on_screen":true,"value":"ebooks","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.31923383,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.31923383,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.31923383,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Documents","depth":7,"bounds":{"left":0.5827792,"top":0.33519554,"width":0.025930852,"height":0.012769354},"on_screen":true,"value":"Documents","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-3541471127704637565
|
-5433410839889920281
|
idle
|
accessibility
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
Hide
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
Youtube
--
--
Sharepoint
Work
--
--
Sharepoint
Test
--
--
Sharepoint
screenpipe
--
--
Sharepoint
personal_folder
--
--
Sharepoint
Music
--
--
Sharepoint
Movies
--
--
Sharepoint
Media
--
--
Sharepoint
Marti
--
--
Sharepoint
Google
--
--
Sharepoint
games
--
--
Sharepoint
Family tree documents
--
--
Sharepoint
EFI
--
--
Sharepoint
ebooks
--
--
Sharepoint
Documents...
|
55352
|
NULL
|
NULL
|
NULL
|
|
55357
|
1917
|
1
|
2026-05-18T14:03:54.480206+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113034480_m2.jpg...
|
Firefox
|
Google Meet — Work
|
1
|
meet.google.com/landing?authuser=lukas.kovalik@jim meet.google.com/landing?authuser=lukas.kovalik@jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
rindelWindowmelprTavsco.s°9 master k >ProleteyC rindelWindowmelprTavsco.s°9 master k >ProleteyCActivityController.ong© SoftPhoneManager.php@) PeindexForUserJob.ongketrуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_A keDors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.ohoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.onvCalendarv 17Cmm› M Delete> M Hubsoot> IM Salesforce(c) Autoloabelavedtocrm.nhnl(C) CoreUserRequest.onpscimProvistoning.ong© CoreUser.php© Activity/Close/service.php© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mpLements Shouldoueueorivatetunction runor ActivtvmoortResult$this->import->getEndDateO$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])Sthis->import->getActivityIdOrecurn (new Acciv1cylmporckesulcoo->secToraLsimporceokecoros.->addimportedSimportedRecords)1631private function complete(ActivityImportResult $result): voidWiminny) Services Activitv RinaCentral Service.imoortData in.. X.• Mothadl(m d importData service ...app/services/Activity RinaCentra• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resultiv D app/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul= custom.log= laravel.logA console [STAGING]© Coachtinal class coaching29 O;34 0 >45 6t >118119130136 @>public function slpubuic tunction glpublic function ti1 usageprivate functionpublac function qu1lusadeorivate Functionpublic function gF1 109m 14cl405 GR100% LzMon 18 May 17:03:5488MCu searchondre colt lag.Actionv Date ModifiedFavourites• jiminny(• AirDrop¿) Recents|A Applications9 Documents(• Downloadcn lukas• iCloud Drive999 Sunc tolderl DxP4800PLUS-Bor4 Network• CRM• Orange• Red• Yellow• Greero Bue• Purple• All Tags...DXP4800PLUS-B5Fback/rorwareconnected as: AdminEi Youtubett worktl TestEl personal_folder*MUSICtim Moviest Mediau MaruiE Googlel ramily tree documentsfashonke# DocumentsdockeH RTfim bookdrorEm BackupAudiobooksEm AppsSharepoinsnarepoint-- Sharenoint= Sharepoint- Sharenoint- Sharenointsharepolnt...
|
NULL
|
973798087542891638
|
NULL
|
click
|
ocr
|
NULL
|
rindelWindowmelprTavsco.s°9 master k >ProleteyC rindelWindowmelprTavsco.s°9 master k >ProleteyCActivityController.ong© SoftPhoneManager.php@) PeindexForUserJob.ongketrуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_A keDors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.ohoc) SendReportJob.phpc) SendRevortMai.loo.onvc) SendReoortNotGeneratedMail.loo.onvCalendarv 17Cmm› M Delete> M Hubsoot> IM Salesforce(c) Autoloabelavedtocrm.nhnl(C) CoreUserRequest.onpscimProvistoning.ong© CoreUser.php© Activity/Close/service.php© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mpLements Shouldoueueorivatetunction runor ActivtvmoortResult$this->import->getEndDateO$this->userRepository->findOneBy(['id' => $this->import->getUserIdO])Sthis->import->getActivityIdOrecurn (new Acciv1cylmporckesulcoo->secToraLsimporceokecoros.->addimportedSimportedRecords)1631private function complete(ActivityImportResult $result): voidWiminny) Services Activitv RinaCentral Service.imoortData in.. X.• Mothadl(m d importData service ...app/services/Activity RinaCentra• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resultiv D app/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resul= custom.log= laravel.logA console [STAGING]© Coachtinal class coaching29 O;34 0 >45 6t >118119130136 @>public function slpubuic tunction glpublic function ti1 usageprivate functionpublac function qu1lusadeorivate Functionpublic function gF1 109m 14cl405 GR100% LzMon 18 May 17:03:5488MCu searchondre colt lag.Actionv Date ModifiedFavourites• jiminny(• AirDrop¿) Recents|A Applications9 Documents(• Downloadcn lukas• iCloud Drive999 Sunc tolderl DxP4800PLUS-Bor4 Network• CRM• Orange• Red• Yellow• Greero Bue• Purple• All Tags...DXP4800PLUS-B5Fback/rorwareconnected as: AdminEi Youtubett worktl TestEl personal_folder*MUSICtim Moviest Mediau MaruiE Googlel ramily tree documentsfashonke# DocumentsdockeH RTfim bookdrorEm BackupAudiobooksEm AppsSharepoinsnarepoint-- Sharenoint= Sharepoint- Sharenoint- Sharenointsharepolnt...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55355
|
1916
|
1
|
2026-05-18T14:03:54.485114+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113034485_m1.jpg...
|
Firefox
|
Google Meet — Work
|
1
|
meet.google.com/landing?authuser=lukas.kovalik@jim meet.google.com/landing?authuser=lukas.kovalik@jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Finder FileEdit ViewGoWindowHelp••0 <→ X• =@ me Finder FileEdit ViewGoWindowHelp••0 <→ X• =@ meet.google.com/landing?authuser=[EMAIL]= [1 Google Meet* 100% C4 &• Mon 18 May 17:03:545:03 PM • Mon, May 18+MeetingsD* CallsSecure video conferencingfor everyoneConnect, collaborate, and celebrate from anywhere withGoogle MeetEK New meetingEnter a code or nicknameJoin |4:00 PM[Platform] Refinement &From your Google Calendar account: [EMAIL] more about Google Meet...
|
NULL
|
8103901336655607198
|
NULL
|
click
|
ocr
|
NULL
|
Finder FileEdit ViewGoWindowHelp••0 <→ X• =@ me Finder FileEdit ViewGoWindowHelp••0 <→ X• =@ meet.google.com/landing?authuser=[EMAIL]= [1 Google Meet* 100% C4 &• Mon 18 May 17:03:545:03 PM • Mon, May 18+MeetingsD* CallsSecure video conferencingfor everyoneConnect, collaborate, and celebrate from anywhere withGoogle MeetEK New meetingEnter a code or nicknameJoin |4:00 PM[Platform] Refinement &From your Google Calendar account: [EMAIL] more about Google Meet...
|
55353
|
NULL
|
NULL
|
NULL
|
|
55356
|
1916
|
2
|
2026-05-18T14:03:55.611214+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113035611_m1.jpg...
|
Firefox
|
Google Meet — Work
|
1
|
meet.google.com/landing?authuser=lukas.kovalik@jim meet.google.com/landing?authuser=lukas.kovalik@jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Google Meet
Close tab
New Tab
Open Google Gemini ( Google Meet
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Main menu
Google Meet
Meet
5:03 PM
•
Mon, May 18
Support
Report a problem
Settings
Google apps
Google Account: [EMAIL]
Meetings
Meetings
Calls
Calls
Secure video conferencing for everyone
Secure video conferencing for everyone
Connect, collaborate, and celebrate from anywhere with
Google Meet
New meeting
New meeting
Enter a code or nickname
Join
Join
4:00 PM to 5:00 PM. [Platform] Refinement 🔍.
4:00 PM
[Platform] Refinement 🔍
From your Google Calendar account: [EMAIL]
Learn more about Google Meet
Learn more
about Google Meet...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Google Meet","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Main menu","depth":9,"bounds":{"left":0.042013887,"top":0.08111111,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXLink","text":"Google Meet","depth":10,"bounds":{"left":0.078125,"top":0.083333336,"width":0.12326389,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Meet","depth":12,"bounds":{"left":0.16701388,"top":0.093333334,"width":0.034375,"height":0.030555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5:03 PM","depth":10,"bounds":{"left":0.7114583,"top":0.095,"width":0.044444446,"height":0.025555555},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":10,"bounds":{"left":0.75590277,"top":0.095,"width":0.010416667,"height":0.025555555},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mon, May 18","depth":10,"bounds":{"left":0.76631945,"top":0.095,"width":0.06979167,"height":0.025555555},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Support","depth":11,"bounds":{"left":0.84444445,"top":0.08555555,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Report a problem","depth":11,"bounds":{"left":0.87222224,"top":0.08555555,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Settings","depth":11,"bounds":{"left":0.9,"top":0.08555555,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Google apps","depth":11,"bounds":{"left":0.9291667,"top":0.08555555,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Google Account: lukas.kovalik@jiminny.com","depth":11,"bounds":{"left":0.9625,"top":0.08555555,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Meetings","depth":11,"bounds":{"left":0.033680554,"top":0.17,"width":0.17777778,"height":0.062222224},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Meetings","depth":14,"bounds":{"left":0.072569445,"top":0.19,"width":0.04826389,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Calls","depth":11,"bounds":{"left":0.033680554,"top":0.23222223,"width":0.17777778,"height":0.062222224},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Calls","depth":14,"bounds":{"left":0.072569445,"top":0.2522222,"width":0.025,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Secure video conferencing for everyone","depth":10,"bounds":{"left":0.40034723,"top":0.305,"width":0.41111112,"height":0.12444445},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Secure video conferencing for everyone","depth":11,"bounds":{"left":0.41805556,"top":0.30222222,"width":0.37534723,"height":0.12055556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Connect, collaborate, and celebrate from anywhere with","depth":11,"bounds":{"left":0.41284722,"top":0.42944443,"width":0.38576388,"height":0.031111112},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet","depth":11,"bounds":{"left":0.56041664,"top":0.46055555,"width":0.090625,"height":0.031111112},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New meeting","depth":11,"bounds":{"left":0.40034723,"top":0.5272222,"width":0.10138889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New meeting","depth":13,"bounds":{"left":0.43090278,"top":0.54333335,"width":0.059722222,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Enter a code or nickname","depth":10,"bounds":{"left":0.54895836,"top":0.5272222,"width":0.15486111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Join","depth":11,"bounds":{"left":0.7204861,"top":0.5272222,"width":0.044444446,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join","depth":13,"bounds":{"left":0.7329861,"top":0.54333335,"width":0.019097222,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"4:00 PM to 5:00 PM. [Platform] Refinement 🔍.","depth":11,"bounds":{"left":0.38993055,"top":0.66944444,"width":0.43159723,"height":0.07611111},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"4:00 PM","depth":13,"bounds":{"left":0.40763888,"top":0.69666666,"width":0.04236111,"height":0.021666666},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[Platform] Refinement 🔍","depth":13,"bounds":{"left":0.48541668,"top":0.6933333,"width":0.15,"height":0.028333334},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"From your Google Calendar account: lukas.kovalik@jiminny.com","depth":11,"bounds":{"left":0.40034723,"top":0.78444445,"width":0.23680556,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about Google Meet","depth":11,"bounds":{"left":0.40034723,"top":0.8211111,"width":0.043402776,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":12,"bounds":{"left":0.40034723,"top":0.8211111,"width":0.043402776,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"about Google Meet","depth":11,"bounds":{"left":0.44375,"top":0.8211111,"width":0.07638889,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-5016981023910470860
|
1159086965481034118
|
visual_change
|
accessibility
|
NULL
|
Google Meet
Close tab
New Tab
Open Google Gemini ( Google Meet
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Main menu
Google Meet
Meet
5:03 PM
•
Mon, May 18
Support
Report a problem
Settings
Google apps
Google Account: [EMAIL]
Meetings
Meetings
Calls
Calls
Secure video conferencing for everyone
Secure video conferencing for everyone
Connect, collaborate, and celebrate from anywhere with
Google Meet
New meeting
New meeting
Enter a code or nickname
Join
Join
4:00 PM to 5:00 PM. [Platform] Refinement 🔍.
4:00 PM
[Platform] Refinement 🔍
From your Google Calendar account: [EMAIL]
Learn more about Google Meet
Learn more
about Google Meet...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55359
|
1917
|
2
|
2026-05-18T14:03:57.367042+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113037367_m2.jpg...
|
Firefox
|
Work item search - Jira — Work
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Work item search - Jira
Work item search - Jira
Cl Work item search - Jira
Work item search - Jira
Close tab
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Usage | Windsurf
Usage | Windsurf
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
Jiminny
Jiminny
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
New Tab
New Tab
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20879] Enable users to use their new activity types - Jira
[JY-20879] Enable users to use their new activity types - Jira
Project Phoenix – Figma
Project Phoenix – Figma
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Resolver
Resolver
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Work item search - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Work item search - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.040392287,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.05905826,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.10721409,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.029920213,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.1796875,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.06632314,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.041223403,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.041223403,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny\\Exceptions\\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app","depth":4,"bounds":{"left":0.0,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app","depth":5,"bounds":{"left":0.013297873,"top":0.3575419,"width":0.2847407,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.39026338,"width":0.1796875,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira","depth":4,"bounds":{"left":0.0,"top":0.41181165,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.42298484,"width":0.2835771,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.4445331,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.4557063,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira","depth":4,"bounds":{"left":0.0,"top":0.4772546,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.4884278,"width":0.15259309,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20771] Call Scoring filter for Exec reports - Jira","depth":4,"bounds":{"left":0.0,"top":0.509976,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20771] Call Scoring filter for Exec reports - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.5211492,"width":0.08909574,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira","depth":4,"bounds":{"left":0.0,"top":0.54269755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.55387074,"width":0.13597074,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20879] Enable users to use their new activity types - Jira","depth":4,"bounds":{"left":0.0,"top":0.575419,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20879] Enable users to use their new activity types - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.5865922,"width":0.106715426,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Project Phoenix – Figma","depth":4,"bounds":{"left":0.0,"top":0.60814047,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Phoenix – Figma","depth":5,"bounds":{"left":0.013297873,"top":0.61931366,"width":0.041888297,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20847] Users can filter Scores in Team Insights by Host - Jira","depth":4,"bounds":{"left":0.0,"top":0.6408619,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20847] Users can filter Scores in Team Insights by Host - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.6520351,"width":0.1143617,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20534] AI Call Scoring quick access in Playback header - Jira","depth":4,"bounds":{"left":0.0,"top":0.6735834,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20534] AI Call Scoring quick access in Playback header - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.6847566,"width":0.1143617,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.70790106,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.090259306,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.090259306,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.090259306,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.090259306,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.090259306,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.090259306,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.090259306,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.08361037,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.0887633,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.095578454,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.10073138,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.10887633,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Resolver","depth":11,"bounds":{"left":0.40475398,"top":0.06264964,"width":0.24268617,"height":0.015961692},"on_screen":true,"value":"Resolver","help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Resolver","depth":12,"bounds":{"left":0.40475398,"top":0.06384677,"width":0.018949468,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.65575135,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.66705453,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.91223407,"top":0.057861134,"width":0.035904255,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.92353725,"top":0.06384677,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.9494681,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.954621,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.96143615,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.9665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.9734042,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.97855717,"top":0.06344773,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.98537236,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.99052525,"top":0.06344773,"width":0.009474754,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.08361037,"top":0.09976058,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.09424867,"top":0.10574621,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.08361037,"top":0.12529927,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recent","depth":15,"bounds":{"left":0.09424867,"top":0.13128492,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
8382591057431581989
|
-2880878243941395560
|
visual_change
|
accessibility
|
NULL
|
Work item search - Jira
Work item search - Jira
Cl Work item search - Jira
Work item search - Jira
Close tab
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Usage | Windsurf
Usage | Windsurf
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
Jiminny
Jiminny
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
New Tab
New Tab
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20879] Enable users to use their new activity types - Jira
[JY-20879] Enable users to use their new activity types - Jira
Project Phoenix – Figma
Project Phoenix – Figma
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Resolver
Resolver
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent...
|
55357
|
NULL
|
NULL
|
NULL
|
|
55358
|
1916
|
3
|
2026-05-18T14:03:57.461468+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113037461_m1.jpg...
|
Firefox
|
Work item search - Jira — Work
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Work item search - Jira
Work item search - Jira
Cl Work item search - Jira
Work item search - Jira
Close tab
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Usage | Windsurf
Usage | Windsurf
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
Jiminny
Jiminny
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
New Tab
New Tab
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20879] Enable users to use their new activity types - Jira
[JY-20879] Enable users to use their new activity types - Jira
Project Phoenix – Figma
Project Phoenix – Figma
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Resolver
Resolver
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Work item search - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Work item search - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny\\Exceptions\\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20771] Call Scoring filter for Exec reports - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20771] Call Scoring filter for Exec reports - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20879] Enable users to use their new activity types - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20879] Enable users to use their new activity types - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Project Phoenix – Figma","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Phoenix – Figma","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20847] Users can filter Scores in Team Insights by Host - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20847] Users can filter Scores in Team Insights by Host - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20534] AI Call Scoring quick access in Playback header - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20534] AI Call Scoring quick access in Playback header - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Resolver","depth":11,"on_screen":true,"value":"Resolver","help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Resolver","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recent","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
8382591057431581989
|
-2880878243941395560
|
click
|
accessibility
|
NULL
|
Work item search - Jira
Work item search - Jira
Cl Work item search - Jira
Work item search - Jira
Close tab
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Usage | Windsurf
Usage | Windsurf
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
Jiminny
Jiminny
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
New Tab
New Tab
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20879] Enable users to use their new activity types - Jira
[JY-20879] Enable users to use their new activity types - Jira
Project Phoenix – Figma
Project Phoenix – Figma
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Resolver
Resolver
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent...
|
55356
|
NULL
|
NULL
|
NULL
|
|
55360
|
1916
|
4
|
2026-05-18T14:03:58.655730+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113038655_m1.jpg...
|
Firefox
|
Work item search - Jira — Work
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Work item search - Jira
Work item search - Jira
Cl Work item search - Jira
Work item search - Jira
Close tab
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Usage | Windsurf
Usage | Windsurf
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
Jiminny
Jiminny
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
New Tab
New Tab
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20879] Enable users to use their new activity types - Jira
[JY-20879] Enable users to use their new activity types - Jira
Project Phoenix – Figma
Project Phoenix – Figma
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Resolver
Resolver
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
More spaces
More spaces
Filters
Filters
More actions for Filters
More actions for Filters
Search work items
Search work items
Starred
Last commented
Last commented
More actions for Last commented
More actions for Last commented
My tickets...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Work item search - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Work item search - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Usage | Windsurf","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Usage | Windsurf","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6848] Sidekick SMS issue - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny\\Exceptions\\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20771] Call Scoring filter for Exec reports - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20771] Call Scoring filter for Exec reports - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20879] Enable users to use their new activity types - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20879] Enable users to use their new activity types - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Project Phoenix – Figma","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Phoenix – Figma","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20847] Users can filter Scores in Team Insights by Host - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20847] Users can filter Scores in Team Insights by Host - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20534] AI Call Scoring quick access in Playback header - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20534] AI Call Scoring quick access in Playback header - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Resolver","depth":11,"on_screen":true,"value":"Resolver","help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Resolver","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recent","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Starred","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Apps","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXMenuButton","text":"Create board","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Team","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Team","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Capture Team","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Capture Team","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Enterprise Stability Issues 🤕","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enterprise Stability Issues 🤕","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Processing Team","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Processing Team","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SE Kanban","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SE Kanban","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Service-Desk","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More spaces","depth":17,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More spaces","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Filters","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Filters","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Filters","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Search work items","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search work items","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Starred","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Last commented","depth":17,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Last commented","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Last commented","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Last commented","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"My tickets","depth":17,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
5441740884184961082
|
5914660109278826904
|
visual_change
|
accessibility
|
NULL
|
Work item search - Jira
Work item search - Jira
Cl Work item search - Jira
Work item search - Jira
Close tab
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Usage | Windsurf
Usage | Windsurf
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
[SRD-6848] Sidekick SMS issue - Jira
[SRD-6848] Sidekick SMS issue - Jira
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
CloudWatch | us-east-2
Jiminny
Jiminny
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Jiminny\Exceptions\SocialAccountTokenInvalidException: Your Salesforce account has become disconnected. Please login to Jiminny to reconnect. — jiminny — app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
Allow owner's role to be selected when setting up a trial by LakyLak · Pull Request #12092 · jiminny/app
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
[SRD-6862] ‘User does not have any of the necessary access rights’ when trying to see another team’s performance scored with the AI ACS in team insights. - Jira
New Tab
New Tab
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20912] Fallback mechanism for users with active SF tokens for CRM Matching - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20771] Call Scoring filter for Exec reports - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20878] SCIM > Allow customers to manage user roles through SCIM - Jira
[JY-20879] Enable users to use their new activity types - Jira
[JY-20879] Enable users to use their new activity types - Jira
Project Phoenix – Figma
Project Phoenix – Figma
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20847] Users can filter Scores in Team Insights by Host - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
[JY-20534] AI Call Scoring quick access in Playback header - Jira
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Resolver
Resolver
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
More spaces
More spaces
Filters
Filters
More actions for Filters
More actions for Filters
Search work items
Search work items
Starred
Last commented
Last commented
More actions for Last commented
More actions for Last commented
My tickets...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55361
|
1917
|
3
|
2026-05-18T14:04:00.376803+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113040376_m2.jpg...
|
Finder
|
DXP4800PLUS-B5F
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
Youtube
--
--
Sharepoint
Work
--
--
Sharepoint
Test
--
--
Sharepoint
screenpipe
--
--
Sharepoint
personal_folder
--
--
Sharepoint
Music
--
--
Sharepoint
Movies
--
--
Sharepoint
Media
--
--
Sharepoint
Marti
--...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Favourites","depth":6,"bounds":{"left":0.5046542,"top":0.061452515,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"jiminny","depth":6,"bounds":{"left":0.51263297,"top":0.08140463,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AirDrop","depth":6,"bounds":{"left":0.51263297,"top":0.103751,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Recents","depth":6,"bounds":{"left":0.51263297,"top":0.12609737,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Applications","depth":6,"bounds":{"left":0.51263297,"top":0.14844373,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Documents","depth":6,"bounds":{"left":0.51263297,"top":0.1707901,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Downloads","depth":6,"bounds":{"left":0.51263297,"top":0.19313647,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lukas","depth":6,"bounds":{"left":0.51263297,"top":0.21548285,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"iCloud","depth":6,"bounds":{"left":0.5046542,"top":0.2434158,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"iCloud Drive","depth":6,"bounds":{"left":0.51263297,"top":0.26336792,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sync folder","depth":6,"bounds":{"left":0.51263297,"top":0.2857143,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locations","depth":6,"bounds":{"left":0.5046542,"top":0.31364724,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":6,"bounds":{"left":0.51263297,"top":0.33359936,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Network","depth":6,"bounds":{"left":0.51263297,"top":0.35594574,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tags","depth":6,"bounds":{"left":0.5046542,"top":0.38387868,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"CRM","depth":6,"bounds":{"left":0.51263297,"top":0.4038308,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Orange","depth":6,"bounds":{"left":0.51263297,"top":0.42617717,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Red","depth":6,"bounds":{"left":0.51263297,"top":0.44852355,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yellow","depth":6,"bounds":{"left":0.51263297,"top":0.4708699,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Green","depth":6,"bounds":{"left":0.51263297,"top":0.49321628,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blue","depth":6,"bounds":{"left":0.51263297,"top":0.51556265,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Purple","depth":6,"bounds":{"left":0.51263297,"top":0.53790903,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"All Tags…","depth":6,"bounds":{"left":0.51263297,"top":0.5602554,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Name","depth":7,"bounds":{"left":0.5827792,"top":0.08858739,"width":0.011968086,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Date Modified","depth":7,"bounds":{"left":0.8656915,"top":0.08858739,"width":0.025930852,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Size","depth":7,"bounds":{"left":0.92586434,"top":0.08858739,"width":0.008976064,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Kind","depth":7,"bounds":{"left":0.9581117,"top":0.08858739,"width":0.00930851,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Youtube","depth":7,"bounds":{"left":0.5827792,"top":0.11173184,"width":0.019281914,"height":0.012769354},"on_screen":true,"value":"Youtube","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.11173184,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.11173184,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.11173184,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Work","depth":7,"bounds":{"left":0.5827792,"top":0.12769353,"width":0.013297873,"height":0.012769354},"on_screen":true,"value":"Work","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.12769353,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.12769353,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.12769353,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Test","depth":7,"bounds":{"left":0.5827792,"top":0.14365523,"width":0.011303191,"height":0.012769354},"on_screen":true,"value":"Test","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.14365523,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.14365523,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.14365523,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"screenpipe","depth":7,"bounds":{"left":0.5827792,"top":0.15961692,"width":0.025265958,"height":0.012769354},"on_screen":true,"value":"screenpipe","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.15961692,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.15961692,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.15961692,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"personal_folder","depth":7,"bounds":{"left":0.5827792,"top":0.17557861,"width":0.034242023,"height":0.012769354},"on_screen":true,"value":"personal_folder","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.17557861,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.17557861,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.17557861,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Music","depth":7,"bounds":{"left":0.5827792,"top":0.1915403,"width":0.01462766,"height":0.012769354},"on_screen":true,"value":"Music","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.1915403,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.1915403,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.1915403,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Movies","depth":7,"bounds":{"left":0.5827792,"top":0.207502,"width":0.016954787,"height":0.012769354},"on_screen":true,"value":"Movies","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.207502,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.207502,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.207502,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Media","depth":7,"bounds":{"left":0.5827792,"top":0.22346368,"width":0.014960106,"height":0.012769354},"on_screen":true,"value":"Media","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.22346368,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.9494681,"top":0.22346368,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sharepoint","depth":7,"bounds":{"left":0.9581117,"top":0.22346368,"width":0.023271276,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextField","text":"Marti","depth":7,"bounds":{"left":0.5827792,"top":0.23942538,"width":0.013297873,"height":0.012769354},"on_screen":true,"value":"Marti","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"--","depth":7,"bounds":{"left":0.8656915,"top":0.23942538,"width":0.056848403,"height":0.012769354},"on_screen":true,"role_description":"text"}]...
|
-52225687295284565
|
-6586336725294202905
|
visual_change
|
accessibility
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue
Purple
All Tags…
Name
Date Modified
Size
Kind
Youtube
--
--
Sharepoint
Work
--
--
Sharepoint
Test
--
--
Sharepoint
screenpipe
--
--
Sharepoint
personal_folder
--
--
Sharepoint
Music
--
--
Sharepoint
Movies
--
--
Sharepoint
Media
--
--
Sharepoint
Marti
--...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55363
|
1917
|
4
|
2026-05-18T14:04:00.968401+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113040968_m2.jpg...
|
Finder
|
DXP4800PLUS-B5F
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Favourites","depth":6,"bounds":{"left":0.5046542,"top":0.061452515,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"jiminny","depth":6,"bounds":{"left":0.51263297,"top":0.08140463,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AirDrop","depth":6,"bounds":{"left":0.51263297,"top":0.103751,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Recents","depth":6,"bounds":{"left":0.51263297,"top":0.12609737,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Applications","depth":6,"bounds":{"left":0.51263297,"top":0.14844373,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Documents","depth":6,"bounds":{"left":0.51263297,"top":0.1707901,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Downloads","depth":6,"bounds":{"left":0.51263297,"top":0.19313647,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lukas","depth":6,"bounds":{"left":0.51263297,"top":0.21548285,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"iCloud","depth":6,"bounds":{"left":0.5046542,"top":0.2434158,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"iCloud Drive","depth":6,"bounds":{"left":0.51263297,"top":0.26336792,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sync folder","depth":6,"bounds":{"left":0.51263297,"top":0.2857143,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locations","depth":6,"bounds":{"left":0.5046542,"top":0.31364724,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":6,"bounds":{"left":0.51263297,"top":0.33359936,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Network","depth":6,"bounds":{"left":0.51263297,"top":0.35594574,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tags","depth":6,"bounds":{"left":0.5046542,"top":0.38387868,"width":0.06216755,"height":0.015163607},"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"CRM","depth":6,"bounds":{"left":0.51263297,"top":0.4038308,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Orange","depth":6,"bounds":{"left":0.51263297,"top":0.42617717,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Red","depth":6,"bounds":{"left":0.51263297,"top":0.44852355,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yellow","depth":6,"bounds":{"left":0.51263297,"top":0.4708699,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Green","depth":6,"bounds":{"left":0.51263297,"top":0.49321628,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blue","depth":6,"bounds":{"left":0.51263297,"top":0.51556265,"width":0.049534574,"height":0.012769354},"on_screen":true,"role_description":"text"}]...
|
86037285638829498
|
-6415058807730911344
|
click
|
accessibility
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue...
|
55361
|
NULL
|
NULL
|
NULL
|
|
55362
|
1916
|
5
|
2026-05-18T14:04:00.972640+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113040972_m1.jpg...
|
Finder
|
DXP4800PLUS-B5F
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Favourites","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"jiminny","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AirDrop","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Recents","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Applications","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Documents","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Downloads","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lukas","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"iCloud","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"iCloud Drive","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sync folder","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locations","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"DXP4800PLUS-B5F","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Network","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tags","depth":6,"on_screen":true,"automation_id":"xSidebarHeader","role_description":"text"},{"role":"AXStaticText","text":"CRM","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Orange","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Red","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yellow","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Green","depth":6,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Blue","depth":6,"on_screen":true,"role_description":"text"}]...
|
86037285638829498
|
-6415058807730911344
|
click
|
accessibility
|
NULL
|
Favourites
jiminny
AirDrop
Recents
Applications
Do Favourites
jiminny
AirDrop
Recents
Applications
Documents
Downloads
lukas
iCloud
iCloud Drive
Sync folder
Locations
DXP4800PLUS-B5F
Network
Tags
CRM
Orange
Red
Yellow
Green
Blue...
|
55360
|
NULL
|
NULL
|
NULL
|
|
55364
|
1917
|
5
|
2026-05-18T14:04:03.407514+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113043407_m2.jpg...
|
Finder
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
The operation can’t be completed because the origi The operation can’t be completed because the original item for “Work” can’t be found.
OK...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"The operation can’t be completed because the original item for “Work” can’t be found.","depth":1,"bounds":{"left":0.46276596,"top":0.3056664,"width":0.07446808,"height":0.03830806},"on_screen":true,"lines":[{"char_start":0,"char_count":23,"bounds":{"left":0.47583437,"top":0.3056664,"width":0.049420133,"height":0.012769354}},{"char_start":23,"char_count":31,"bounds":{"left":0.46629918,"top":0.31843576,"width":0.068490535,"height":0.012769354}},{"char_start":54,"char_count":31,"bounds":{"left":0.46634772,"top":0.3312051,"width":0.067304574,"height":0.012769354}}],"automation_id":"_NS:78","role_description":"text"},{"role":"AXButton","text":"OK","depth":1,"bounds":{"left":0.46010637,"top":0.3519553,"width":0.07978723,"height":0.031923383},"on_screen":true,"automation_id":"action-button--998","role_description":"button","is_enabled":true,"is_focused":true}]...
|
7831856516432088658
|
5041192683375478396
|
visual_change
|
hybrid
|
NULL
|
The operation can’t be completed because the origi The operation can’t be completed because the original item for “Work” can’t be found.
OK
rindel+ Work item search - JiraService-Desk - Queues - Platfornw Usage | WindsurfAllow owner's role to be selectedPipelines - jiminny/appN1 (SRD-6848] Sidekick SMS issue -CloudWatch I us-east-2CloudWatch | us-east-28 Jiminnys) Jiminny\Exceptions|SocialAccountAllow owner's role to be selectedU ISRD-68621 'User does not have al* New Tab(JY-209121 Fallback mechanism fcS MIY-207711 Call Scorina filter for &(UY-20878] SCIM > Allow custome- WJY-208791 Enable users to use thProject Phoenix - Figma(UY-20847] Users can filter ScoresLIY-205341 Al Call Scorina quick al- New TabF1 109m 14cl405 GRWindowMelpO JIMINNY@ For you(• Recent# Starred0+ Apps• Spaces+ ***Jiminny (New)ull Plarorm leamIID Capture TeamID Enterprise Stability I…..IN Processing TeamMl SE KanbanC Service-Desk= More spaces= Filters1 Q Search work items- ast commented= My tickets= (SRD)— Dialers & CRM Team > ...~ Nefault filterc I= My open work items= Reported by me= All work items= Open work items= Done work items= Viewed recently= Created recently= Resolved recentlv= Updated recently= View all filters( DashboardsC: Operations& ConfluenceAll work* Ask AIBasictextfields ~ "Resolver*"JY-16891 Refactor transcription providers flowI JY-14913 Check if a transcription mode is allowed before using it as override# JY-12384 Uploader > create a new platform for uploaded callsO JY-11338 Remove supportChannelDiarization method and use track channelsN JY-10b// Allow dialer soecitic rules tor particioanis creation# JMNY-6785 Users must finish onboarding to be able to use the dialerO JMNY-3404 Define and configure data payloads9 JMNY-3112 Imolement soft-deletion of transcriotion model locale entriesQ ResolverAssigneeReporter& Unassignedg UnassignedI Ilian Kyuchuko© Kaloyan Nikola.1 Tonislav AtanaOKcuvated)Ed Nikola Petkanski (Dea... James Graham& Unassigned• James Graham( James GrahamNikola Petkanski (Deactivated)Priority= Medium= Medium= Medium= Medium= MediumNone= Medium= Medium8of8 5StatusBACKLOGVBACKLOGVCLOSED VCLOSEDVCLOSEDNEW ISSUESICEBOXCLOSED V+ CreateResolutionUnresolvedUnresolvedUnresolvedUnresolvedUnresolvedUnresolvedUnresolvedUnresolvedCreated12 Feb 2025, 12:2727 Sept 2024, 09:3805 Apr 2024, 09:0430 Jan 2024, 13:4027 Nov 2023, 15:0715 Jul 2019, 21:5007 Mar 2019, 12:4807 Nov 2018, 09:06Updated12 Feb 2025, 12:4827 Sept 2024, 09:3802 Sept 2024, 16:4302 Sept 2024, 16:3917 Apr 2025, 07:5231 Mar 2022, 13:2405 Apr 2022, 14:4507 Apr 2022, 10:44GOOA 10%9 8• Mn 18 May 17:04:03Due dateNoneNoneNoneNoneNoneNoneNoneNoneLASk ROVO A ® Lô 0Apps ~ Share ~0"O a Clearfilterss Save filterm[PASSWORD_DOTS]...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55365
|
1916
|
6
|
2026-05-18T14:04:05.637446+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779113045637_m1.jpg...
|
Finder
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
The operation can’t be completed because the origi The operation can’t be completed because the original item for “Work” can’t be found.
OK...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"The operation can’t be completed because the original item for “Work” can’t be found.","depth":1,"on_screen":true,"automation_id":"_NS:78","role_description":"text"},{"role":"AXButton","text":"OK","depth":1,"on_screen":true,"automation_id":"action-button--998","role_description":"button","is_enabled":true,"is_focused":true}]...
|
7831856516432088658
|
5041192683375478396
|
click
|
hybrid
|
NULL
|
The operation can’t be completed because the origi The operation can’t be completed because the original item for “Work” can’t be found.
OK
FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpEU (ssh)DOCKER881DEV (-zsh)О $211DOCKER (-zsh)"taskManager"connections"}"taskManager"], "pid"to poll for work: Error: No Li1 {"type": "log", "@timestamp" : "2026-05-18T13:02:06Z","tags" : ["error""pid":7, "message": "[ConnectionError]:getaddrinfoENOTFOUND elasticsearch elasticsearch:9200"}{"type" : "log"sticsearch", "data"], "pid" :7,:"2026-05-18T13:02:07Z""tags": ["warning"connection: [URL_WITH_CREDENTIALS] : "2026-05-18T13:02:07Z", "tags" : ["warning", "elasticsearch", "data"],"pid" :7,"message":"No livingconnections "}kibana1 {"type" : "log""@timestamp": "2026-05-18T13:02:07Z""tags" : ["error"ns""taskManager""taskManager"],"pid":7, "message": "Failed to pollfor work: Error: No Livingconnections"}kibana1 {"type" : "log""@timestamp" : "2026-05-18T13:02:08Z" , "tags" : ["error","elasticsearch".,"data"],"pid" :7, "message":"[ConnectionError]: getaddrinfo ENOTFOUND elasticsearch elasticsearch:9200"}kibana"@timestamp": "2026-05-18T13:02:10Z", "tags" : ["warning""elasticsearch", "data"], "pid":7, "message": "Unable to revive connection: [URL_WITH_CREDENTIALS] : "2026-05-18T13:02:10Z" , "tags" : ["warning"sticsearch", "data"], "pid" :7, "message" : "No living connections"}1 {"type": "log", "@timestamp": "2026-05-18T13:02:10Z""tags" : ["error","plugi,"reporting", "esqueue", "queue-worker","error"], "pid" :7, "message" : "mpau4y7h00070bdf8646mdeo - job querying failed: Error: No Living connections\nat sendReqWithConnection (/usr/share/kibana/node_modules/elasticsearch/src/lib/transport.js:266:15)\nat next (/usr/share/kibana/node_modules/elasticsearch/src/lib/connection_pool.js:243:7)\ness._tickCallback (internal/process/next_tick.js:61:11)"}1 {"type" : "log", "@timestamp" : "2026-05-18T13:02:10Z", "tags" : ["warning", "elasticsearch", "data"], "pid":7, "message" : "Unable to revive connection: [URL_WITH_CREDENTIALS] : "2026-05-18T13:02:10Z", "tags" : ["warning", "elasticsearch", "data"], "pid" :7, "message" : "No living connections"}kibana1 {"type" : "log", "@timestamp" : "2026-05-18T13:02:10Z""tags": ["error"ns", "taskManager", "taskManager"], "pid" :7, "message": "Failed to poll for work: Error: No Living connections"}kibanaI {"type" : "log", "@timestamp" : "2026-05-18T13:02:10Z","tags" : ["error","elasticsearch", "data"], "pid" :7, "message": "[ConnectionError]: getaddrinfo ENOTFOUND elasticsearch elasticsearch:9200"}kibana1 {"type": "log", "@timestamp": "2026-05-18T13:02:11Z", "tags" : ["error","elasticsearch", "data"], "pid" :7,"message": "[ConnectionError]: getaddrinfo ENOTFOUND elasticsearch elasticsearch:9200"}unexpected EOFukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/infrastructure/dev/docker (develop) $‹$0100% <78• Mon 18 May 17:04:05APP (-zsh)• *3t2PROD (ssh)'do-release-upgrade' to upgrade to it.screenpipe*0 84PROD*** System restart required ***Last login: Thu May 14 07:41:36 2026 from 212.5.153.87lukas@jiminny-prod-bastion:~$X T3 EU (ssh)Enable ESM Apps to receive additional future security updates.See [URL_WITH_CREDENTIALS] STAGE (ssh)See [URL_WITH_CREDENTIALS] ~ $ I17 EXT (-zsh)Poetry could not find a pyproject.toml file in /Users/lukas or its parentsPoetry could not find a pyproject.tomlfile in /Users/lukas or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ I|FRONTENDEXTENSION...
|
NULL
|
NULL
|
NULL
|
NULL
|