|
55868
|
1940
|
30
|
2026-05-19T06:59:54.214659+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173994214_m1.jpg...
|
PhpStorm
|
faVsco.js – CoachingFeedbackCoachUserIn.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% C78• Tue 19 May 9:59:54Nikolay Yankov (Presenting)AAFletdtVenTabM Inboka Patto x(] Serwhttps://wppjiminny.com/ai-reports/manageL JehhyProjectsAlk Jimnmy ReportsTue 10 May 9:50© curк© АtонE3 SSHE DatadogAoomareCreate report1. GeneralFREQUENCY +9No esitepaNs menerseo yeNikolay Yankov2. Report parametersATО КАО19Lukas Kovalik9:59 AM|Daily - PlatformLộ314:34::...
|
NULL
|
6435305368804958562
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% C78• Tue 19 May 9:59:54Nikolay Yankov (Presenting)AAFletdtVenTabM Inboka Patto x(] Serwhttps://wppjiminny.com/ai-reports/manageL JehhyProjectsAlk Jimnmy ReportsTue 10 May 9:50© curк© АtонE3 SSHE DatadogAoomareCreate report1. GeneralFREQUENCY +9No esitepaNs menerseo yeNikolay Yankov2. Report parametersATО КАО19Lukas Kovalik9:59 AM|Daily - PlatformLộ314:34::...
|
55867
|
NULL
|
NULL
|
NULL
|
|
55867
|
1940
|
29
|
2026-05-19T06:59:51.201702+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173991201_m1.jpg...
|
PhpStorm
|
faVsco.js – CoachingFeedbackCoachUserIn.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left)100% <8•Tue 19 May 9:59:51Nikolay Yankov (Presenting)AAFleTdtM InboxPlado X12 Servichttps://app.jiminny.com/al-reports/manageL JinyProjectsAsk Jiminny Reports CTue 19 May 9:503 Atten:(a Sche x© ourk xE3 SSHEl Datadogapp.с X AllowlL taskCreate report1. GeneralC DevFREQUENCY €SUWAEUSNoreports have been created yetTEAMMEMBCяNikolay Yankovatо WARCh(9°Lukas Kovalik9:59 AM |Daily - Platform14:31Lộ3...
|
NULL
|
2144791741603754651
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left)100% <8•Tue 19 May 9:59:51Nikolay Yankov (Presenting)AAFleTdtM InboxPlado X12 Servichttps://app.jiminny.com/al-reports/manageL JinyProjectsAsk Jiminny Reports CTue 19 May 9:503 Atten:(a Sche x© ourk xE3 SSHEl Datadogapp.с X AllowlL taskCreate report1. GeneralC DevFREQUENCY €SUWAEUSNoreports have been created yetTEAMMEMBCяNikolay Yankovatо WARCh(9°Lukas Kovalik9:59 AM |Daily - Platform14:31Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55866
|
1940
|
28
|
2026-05-19T06:59:48.224990+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173988224_m1.jpg...
|
PhpStorm
|
faVsco.js – CoachingFeedbackCoachUserIn.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% <28•Tue 19 May 9:59:48Nikolay Yankov (Presenting)AA3M Inbox(7 S[URL_WITH_CREDENTIALS] Exec Summary Podcast - 4 Jan - 17 Oct 2025 - AJl() Exec Summary Podcast - 4 Jan - 17 Oct 2025 - AJlD) Product Feedback - 12 Aug - 15 Sep 2025 - UK SalesD) Exec Summary - 1 Aug - 12 Sep 2025 - UK Sales© Clear allFREQUENCYOne-OffOne-OffOne-OffOnc-OffOne-OftHAXtDATE29/10/202524/10/202524/10/202517/10/202515/09/2025Nikolay YankovLukas Kovalik9:59 AM | Daily - Platform..•14:28=...
|
NULL
|
-4979385676878741450
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% <28•Tue 19 May 9:59:48Nikolay Yankov (Presenting)AA3M Inbox(7 S[URL_WITH_CREDENTIALS] Exec Summary Podcast - 4 Jan - 17 Oct 2025 - AJl() Exec Summary Podcast - 4 Jan - 17 Oct 2025 - AJlD) Product Feedback - 12 Aug - 15 Sep 2025 - UK SalesD) Exec Summary - 1 Aug - 12 Sep 2025 - UK Sales© Clear allFREQUENCYOne-OffOne-OffOne-OffOnc-OffOne-OftHAXtDATE29/10/202524/10/202524/10/202517/10/202515/09/2025Nikolay YankovLukas Kovalik9:59 AM | Daily - Platform..•14:28=...
|
55865
|
NULL
|
NULL
|
NULL
|
|
55865
|
1940
|
27
|
2026-05-19T06:59:45.178835+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173985178_m1.jpg...
|
PhpStorm
|
faVsco.js – CoachingFeedbackCoachUserIn.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
|
[{"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":"AXStaticText","text":"","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":2,"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}]...
|
8043719072324535154
|
-8628527368849355612
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
FirefoxProfilesDaily - Pl Project: faVsco.js, menu
FirefoxProfilesDaily - Platform • 6 m left)100% <28•Tue 19 May 9:59:45$19FileEditViewHistoryBookmarksToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)Q(7 ServicC2 Atben:3 ichen x © cun xhttps://app.jiminny.com/ondemand?sequence_number=2223 SSH38165 activitiesTeannHostUnknown CustomerNotetaker added by Desislav DamryanovAlso search as participantParticipantJon Douglas at GetAgent WJon DouglasCustomer ©Poman Oman at Texas Pools * Poman OmanTAmо ®Atsf Hussain t BornhamaBr* Atir HussinSaid byKirstine Dall at Qarma WSminav xQarma - Hubspot Devp DiveKirstine DallAnyorielBina Mistry at deltatre #* Meet with Oliver from JiminmlBina MistryFerlodAll timeTopkcsJack Ford at Hive WDatoreActivity typeA Thakur at JPA Workspaces #Richard Cooksey and Petico KashinskilA ThalurKelly Klein at Rydoo WXeby Kieln and Georgi BayraktacowKelly KieinDuration ©Min Oninutes)Max (minutes)Clarice Groendal at Map My...#Clarice GroondalAl call score15 aop.dС АвоwA serky X tasSort by: Most recentAсбмку lураCurrent StageDisco/DemoContract SentUS$4,884Conference (Default)CommittedUS$53.760Disco/DemoFree TrialUS$11/172DiscoveryDiscovery Call (upsell)Likely to Renew€8.992Onboarding WorkshopLikely to Reriew£7.034Conference (DefautyUikcly to ReniewC10.923Discovery Call (upsoll)UaxtytoKTUS$6.930Tue 19 May 9:50C Dev@ uxAwemere88)Add RecordQ Get NouihecStatsDuration Daten0 S0 D0 Do 19m19/05/2026.9.55 AMT0 &0 00 D0 27m18/05/2026.6:58PM18/05/2020.6:22 YM20 €0 D0 DO 1218/05/2026, 5:32 PM|D0 40 D0 D0 23m18/05/2026,4:54PMMOGO DO DO18/05/2026, 4:32 PM|MO ₫о Do DO45m18/05/2026.3:4376noco co DoI58m16/05/2026, 258 PM34m18/05/2026, 12:34 PMToc0 0o • 015/05/2026, 7:33 PM|ỮO₫O O DO3/05/7020.5:45 V3Nikolay YankovLukas Kovalik9:59 AM | Daily - Platform..•14:25...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55864
|
1940
|
26
|
2026-05-19T06:59:42.146773+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173982146_m1.jpg...
|
PhpStorm
|
faVsco.js – CoachingFeedbackCoachUserIn.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditView→Nikolay Yankov (Presenting)His FirefoxFileEditView→Nikolay Yankov (Presenting)HistoryBookmarksCh ouueFleTdt2 Platton51 ServiceC Projects12 S5H**19°9:59 AM | Daily - PlatformLộ3ProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% C28• Tue 19 May 9:59:41AA8•Tue 10 May 9:50C Schen© OursoraE Datado e8: Ask Jiminayspp.de xC Аlon3 Pipelin3 Circiecle SerayL tasкinsights & Coachin…Settings# + testC Dev.© Add newNikolay YankovHey Nikolay.It's Jiminny here, how can 1 help?)©) Please noteLukas Kovalik14:22...
|
NULL
|
245137934551375342
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditView→Nikolay Yankov (Presenting)His FirefoxFileEditView→Nikolay Yankov (Presenting)HistoryBookmarksCh ouueFleTdt2 Platton51 ServiceC Projects12 S5H**19°9:59 AM | Daily - PlatformLộ3ProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% C28• Tue 19 May 9:59:41AA8•Tue 10 May 9:50C Schen© OursoraE Datado e8: Ask Jiminayspp.de xC Аlon3 Pipelin3 Circiecle SerayL tasкinsights & Coachin…Settings# + testC Dev.© Add newNikolay YankovHey Nikolay.It's Jiminny here, how can 1 help?)©) Please noteLukas Kovalik14:22...
|
55863
|
NULL
|
NULL
|
NULL
|
|
55862
|
1940
|
24
|
2026-05-19T06:59:37.246496+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173977246_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditView→Nikolay Yankov (Presenting)His FirefoxFileEditView→Nikolay Yankov (Presenting)HistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% C78 • Tue 19 May 9:59:36=FleTất8•Tue 19 May 9:602 PuattoC7 ServiceC Projects(& Schen© Cursorapp.de x.• Home | Salesforce•08 Dtad ©©8. Ask Jimineye senayС Аlо.L taskSettings# + testo PoelrLa insights & CoachinC Dev© Add newNikolay YankovHey NikolayIt's Jiminny here, how can I help?( Please note4 tesLukas Kovalik9:59 AM | Daily - PlatformLộ314:17...
|
NULL
|
-6898993530214123501
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditView→Nikolay Yankov (Presenting)His FirefoxFileEditView→Nikolay Yankov (Presenting)HistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% C78 • Tue 19 May 9:59:36=FleTất8•Tue 19 May 9:602 PuattoC7 ServiceC Projects(& Schen© Cursorapp.de x.• Home | Salesforce•08 Dtad ©©8. Ask Jimineye senayС Аlо.L taskSettings# + testo PoelrLa insights & CoachinC Dev© Add newNikolay YankovHey NikolayIt's Jiminny here, how can I help?( Please note4 tesLukas Kovalik9:59 AM | Daily - PlatformLộ314:17...
|
55861
|
NULL
|
NULL
|
NULL
|
|
55861
|
1940
|
23
|
2026-05-19T06:59:32.240005+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173972240_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Pause
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Pause","depth":2,"bounds":{"left":0.94375,"top":0.0,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"AXStaticText","text":"","depth":2,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":2,"on_screen":true,"role_description":"text"}]...
|
639279736819683987
|
639279736819683987
|
visual_change
|
hybrid
|
NULL
|
Pause
FirefoxFileEdit→ViewHistoryBookmarksProfiles Pause
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 6 m left)100% <28• Tue 19 May 9:59:31=Nikolay Yankov (Presenting)AAFletdtTue 10 May 9:592 PattoC7 Servic x© Curso:app.deProjectsE3 SSHPhpStorm2026.1Nikolay Yankov$L JETBRAINS IDESLukas Kovalik9:59 AM | Daily - Platform14:12Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55860
|
1940
|
22
|
2026-05-19T06:59:27.115719+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173967115_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 6 m left)100% <28 • Tue 19 May 9:59:26)=Nikolay Yankov (Presenting)AAFleTdtTue 19 May 9:502 Plactol51 Service© Oursorapp.deC Projects|E SSHPhpStorm2026.1Nikolay YankovL JETBRAINS IDES19Ack me avthi+ testibout these calls.Lukas Kovalik*9:59 AM | Daily - Platform14:07Lộ3...
|
NULL
|
4479427528527560856
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 6 m left)100% <28 • Tue 19 May 9:59:26)=Nikolay Yankov (Presenting)AAFleTdtTue 19 May 9:502 Plactol51 Service© Oursorapp.deC Projects|E SSHPhpStorm2026.1Nikolay YankovL JETBRAINS IDES19Ack me avthi+ testibout these calls.Lukas Kovalik*9:59 AM | Daily - Platform14:07Lộ3...
|
55859
|
NULL
|
NULL
|
NULL
|
|
55859
|
1940
|
21
|
2026-05-19T06:59:21.945444+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779173961945_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 6 m left)100% <28 • Tue 19 May 9:59:21=Nikolay Yankov (Presenting)AAFlotớtTue 19 May 9:6022 Plattol57 Servicehttps://aco.jiminny.com/dashboard0 Projects© Oursorapp.de Xel ANsE3 SSHNikolew Yackow at Jiminey (EU)P #12 Fcb, 10:19 AMPhpStorm2026.1Nikolay Yankov$O JETBRAINS IDEs19Lukas Kovalik9:59 AM | Daily - Platform14:02...
|
NULL
|
-5346821548277109758
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 6 m left)100% <28 • Tue 19 May 9:59:21=Nikolay Yankov (Presenting)AAFlotớtTue 19 May 9:6022 Plattol57 Servicehttps://aco.jiminny.com/dashboard0 Projects© Oursorapp.de Xel ANsE3 SSHNikolew Yackow at Jiminey (EU)P #12 Fcb, 10:19 AMPhpStorm2026.1Nikolay Yankov$O JETBRAINS IDEs19Lukas Kovalik9:59 AM | Daily - Platform14:02...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55499
|
1924
|
8
|
2026-05-18T15:01:49.502600+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779116509502_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
|
click
|
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
|
|
55498
|
1925
|
5
|
2026-05-18T15:01:49.407270+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779116509407_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...
|
[{"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}]...
|
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
|
|
55497
|
1924
|
7
|
2026-05-18T15:01:47.848299+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779116507848_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FinderFileEditViewGoWindowHelp‹$0100% <78• Mon FinderFileEditViewGoWindowHelp‹$0100% <78• Mon 18 May 18:01:47EU (ssh)DOCKER881DEV (-zsh)О $2X t1DOCKER (-zsh)"taskManager"connections"}"taskManager"],"pid":7,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","@timestamp":"2026-05-18T13:02:07Z""tags": ["warning"sticsearch", "data"], "pid" :7,revive connection: [URL_WITH_CREDENTIALS] "2026-05-18T13:02:07Z", "tags" : ["warning", "elasticsearch","data"], "pid" :7,"message":"No livingconnections "}kibanans"1 {"type" : "log""@timestamp": "2026-05-18T13:02:07Z""tags" : ["error""taskManager""taskManager"],"pid":7, "message": "Failed to pollfor work: Error: No Li1 {"type" : "log""@timestamp" : "2026-05-18T13:02:08Z" , "tags" : ["error""pid" :7, "message": "[ConnectionError]: getaddrinfo ENOTFOUND elasticsearch elasticsearch:9200"}, "@timestamp" : "2026-05-18T13:02:10Z", "tags" : ["warning"sticsearch", "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) $APP (-zsh)• *3t2PROD (ssh)'do-release-upgrade' to upgrade to it.screenpipe"0 ₴4PROD*** 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] [URL_WITH_CREDENTIALS] ~ $ IFRONTENDPoetry 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|EXTENSION...
|
NULL
|
-2990475654208525261
|
NULL
|
click
|
ocr
|
NULL
|
FinderFileEditViewGoWindowHelp‹$0100% <78• Mon FinderFileEditViewGoWindowHelp‹$0100% <78• Mon 18 May 18:01:47EU (ssh)DOCKER881DEV (-zsh)О $2X t1DOCKER (-zsh)"taskManager"connections"}"taskManager"],"pid":7,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","@timestamp":"2026-05-18T13:02:07Z""tags": ["warning"sticsearch", "data"], "pid" :7,revive connection: [URL_WITH_CREDENTIALS] "2026-05-18T13:02:07Z", "tags" : ["warning", "elasticsearch","data"], "pid" :7,"message":"No livingconnections "}kibanans"1 {"type" : "log""@timestamp": "2026-05-18T13:02:07Z""tags" : ["error""taskManager""taskManager"],"pid":7, "message": "Failed to pollfor work: Error: No Li1 {"type" : "log""@timestamp" : "2026-05-18T13:02:08Z" , "tags" : ["error""pid" :7, "message": "[ConnectionError]: getaddrinfo ENOTFOUND elasticsearch elasticsearch:9200"}, "@timestamp" : "2026-05-18T13:02:10Z", "tags" : ["warning"sticsearch", "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) $APP (-zsh)• *3t2PROD (ssh)'do-release-upgrade' to upgrade to it.screenpipe"0 ₴4PROD*** 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] [URL_WITH_CREDENTIALS] ~ $ IFRONTENDPoetry 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|EXTENSION...
|
55495
|
NULL
|
NULL
|
NULL
|
|
55496
|
1925
|
4
|
2026-05-18T15:01:46.379289+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779116506379_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormCoderTavsco.sroledey© ReindexForUserJob.ph PhostormCoderTavsco.sroledey© ReindexForUserJob.phpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_A keDors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.oo.onvc) SendReoortNotGeneratedMail.loo.ondCalendarv 17Cmm>• Delete> M Hubsoot>D Salesforce(c) Autoloabelavedtocrm.nhnlFindWiminny Services Activitv RinaCentral Service.imoortData in.X.v Method(m d importData service ...app/Services/Activity RinaCentra• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resulti~ Dapp/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resulLaravel© BaseService.php© SoftPhoneManager.php© CoreUserRequest.phpscimProvistoning.ong© CoreUser.php© Activity/Close/service.pnp© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueê | Analyzing...orivatetunction runor ActivtvmoortResu.t$this->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO]),$this->import->getActivityId()recurn (new Accivicyimporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)private function complete(ActivityImportResult $result): void=custom.logA console [STAGING]E laravel.log4 SF [jiminny@localhost]A HS_Jocal [jiminny@localhost]A console [PROD]# console [euy© CoachingFeedbackCoachUserin.phpxfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini__construct(UserRepository $userRepository)(...}29 đt >public function shouldApplyQueries(): boolf..;34 đt >public function getQueries(): FilterDefinitionQueryCollectionf...,45 đt >public function toArray(): arrayf…..,118private function getOptions(): arrayf..}public function getValue(): arrayf...,1301 usageprivate function getDefaultValve(): arrayf..,136 Ct>public function getValidationRules(?string $prefix = null): array(...}$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): voiddehdrContiudeuTenantMenaaartorenl heoftthircdmnantbanantldCall Hierarchy100% 28• Mon 18 May 18:01:46SClM Role Manageme+0 ..+40 -1CascadeImplement Trial OwneFixing Redis Rate LimSalestorce Token FalliTnoughts• JiminnyDebugComrAdded 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 (*4D1+ <>Code SWE-1.6165•661f 4 spaces...
|
NULL
|
-3765901566294191776
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhostormCoderTavsco.sroledey© ReindexForUserJob.ph PhostormCoderTavsco.sroledey© ReindexForUserJob.phpketуAcuvilysyncJob.onoleardownstream.onpD AiAutomation_A keDors› EAudiov _ AutomatedReportsC) RequestgenerateReportJob.phoC) SendReportExpirinaSoonMailJob.phoc) SendReportJob.phpc) SendRevortMai.oo.onvc) SendReoortNotGeneratedMail.loo.ondCalendarv 17Cmm>• Delete> M Hubsoot>D Salesforce(c) Autoloabelavedtocrm.nhnlFindWiminny Services Activitv RinaCentral Service.imoortData in.X.v Method(m d importData service ...app/Services/Activity RinaCentra• Usages in Prolect Files 1 resultMethod call 1 resultvcaoo ] resulti~ Dapp/Jobs/Activity 1 resultv (C) Activitv/SvncActivitv.oho 1 resultv (m & run 1 resulLaravel© BaseService.php© SoftPhoneManager.php© CoreUserRequest.phpscimProvistoning.ong© CoreUser.php© Activity/Close/service.pnp© Activity/RingCentral/Service.phpsyncacuiviLy.onp xccrm/close/service.ohoclass Syncactivity extends Job 1mplements Shouldoueueê | Analyzing...orivatetunction runor ActivtvmoortResu.t$this->import->getEndDate(),$this->userRepository->findOneBy(['id' => $this->import->getUserIdO]),$this->import->getActivityId()recurn (new Accivicyimporckesulcoo-›secToraLsimporceokecoros)->addimportedSimportedRecords)private function complete(ActivityImportResult $result): void=custom.logA console [STAGING]E laravel.log4 SF [jiminny@localhost]A HS_Jocal [jiminny@localhost]A console [PROD]# console [euy© CoachingFeedbackCoachUserin.phpxfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini__construct(UserRepository $userRepository)(...}29 đt >public function shouldApplyQueries(): boolf..;34 đt >public function getQueries(): FilterDefinitionQueryCollectionf...,45 đt >public function toArray(): arrayf…..,118private function getOptions(): arrayf..}public function getValue(): arrayf...,1301 usageprivate function getDefaultValve(): arrayf..,136 Ct>public function getValidationRules(?string $prefix = null): array(...}$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): voiddehdrContiudeuTenantMenaaartorenl heoftthircdmnantbanantldCall Hierarchy100% 28• Mon 18 May 18:01:46SClM Role Manageme+0 ..+40 -1CascadeImplement Trial OwneFixing Redis Rate LimSalestorce Token FalliTnoughts• JiminnyDebugComrAdded 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 (*4D1+ <>Code SWE-1.6165•661f 4 spaces...
|
55492
|
NULL
|
NULL
|
NULL
|
|
55495
|
1924
|
6
|
2026-05-18T15:01:46.522379+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779116506522_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncActivity.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FinderFileEditViewGoWindowHelp‹$0100% <78• Mon FinderFileEditViewGoWindowHelp‹$0100% <78• Mon 18 May 18:01:46EU (ssh)DOCKER881DEV (-zsh)О $2X t1DOCKER (-zsh)"taskManager"connections"}"taskManager"],"pid":7,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","@timestamp":"2026-05-18T13:02:07Z""tags": ["warning"sticsearch", "data"], "pid" :7,revive connection: [URL_WITH_CREDENTIALS] "2026-05-18T13:02:07Z", "tags" : ["warning", "elasticsearch","data"], "pid" :7,"message":"No livingconnections "}kibanans"1 {"type" : "log""@timestamp": "2026-05-18T13:02:07Z""tags" : ["error""taskManager""taskManager"],"pid":7, "message": "Failed to pollfor work: Error: No Li1 {"type" : "log""@timestamp" : "2026-05-18T13:02:08Z" , "tags" : ["error""pid" :7, "message": "[ConnectionError]: getaddrinfo ENOTFOUND elasticsearch elasticsearch:9200"}, "@timestamp" : "2026-05-18T13:02:10Z", "tags" : ["warning"sticsearch", "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) $APP (-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] [URL_WITH_CREDENTIALS] ~ $ IFRONTENDPoetry 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|EXTENSION...
|
NULL
|
-3907073204494554170
|
NULL
|
click
|
ocr
|
NULL
|
FinderFileEditViewGoWindowHelp‹$0100% <78• Mon FinderFileEditViewGoWindowHelp‹$0100% <78• Mon 18 May 18:01:46EU (ssh)DOCKER881DEV (-zsh)О $2X t1DOCKER (-zsh)"taskManager"connections"}"taskManager"],"pid":7,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","@timestamp":"2026-05-18T13:02:07Z""tags": ["warning"sticsearch", "data"], "pid" :7,revive connection: [URL_WITH_CREDENTIALS] "2026-05-18T13:02:07Z", "tags" : ["warning", "elasticsearch","data"], "pid" :7,"message":"No livingconnections "}kibanans"1 {"type" : "log""@timestamp": "2026-05-18T13:02:07Z""tags" : ["error""taskManager""taskManager"],"pid":7, "message": "Failed to pollfor work: Error: No Li1 {"type" : "log""@timestamp" : "2026-05-18T13:02:08Z" , "tags" : ["error""pid" :7, "message": "[ConnectionError]: getaddrinfo ENOTFOUND elasticsearch elasticsearch:9200"}, "@timestamp" : "2026-05-18T13:02:10Z", "tags" : ["warning"sticsearch", "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) $APP (-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] [URL_WITH_CREDENTIALS] ~ $ IFRONTENDPoetry 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|EXTENSION...
|
NULL
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
55315
|
1914
|
61
|
2026-05-18T14:01:39.084314+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112899084_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":"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},{"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
|
|
55314
|
1914
|
60
|
2026-05-18T14:01:36.052883+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112896052_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);
}
}...
|
[{"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}]...
|
-819186497728337901
|
-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);
}
}...
|
55313
|
NULL
|
NULL
|
NULL
|
|
55313
|
1914
|
59
|
2026-05-18T14:01:30.003174+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112890003_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":"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}]...
|
-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
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% C8 • Mon 18 May 17:01:29=A05••Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:01 PM | [Platform] Refinement®1:47:56...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55312
|
1914
|
58
|
2026-05-18T14:01:26.970927+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112886970_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...
|
[{"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}]...
|
6088908589105147991
|
-1414059449518157871
|
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...
|
55311
|
NULL
|
NULL
|
NULL
|
|
55311
|
1914
|
57
|
2026-05-18T14:01:20.919063+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112880919_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...
|
[{"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}]...
|
5930764665635139907
|
-1414041857601057839
|
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...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55310
|
1914
|
56
|
2026-05-18T14:01:17.917110+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112877917_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% <78 • Mon 18 May 17:01:175Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:01 PM | [Platform] Refinement®1:47:44...
|
NULL
|
813183072280314651
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistory→BookmarksProfilesToolsW FirefoxFileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% <78 • Mon 18 May 17:01:175Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:01 PM | [Platform] Refinement®1:47:44...
|
55308
|
NULL
|
NULL
|
NULL
|
|
55309
|
1915
|
29
|
2026-05-18T14:01:16.052890+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112876052_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);
}
}...
|
[{"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}]...
|
3303896123807886662
|
-1423066649041924143
|
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);
}
}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55308
|
1914
|
55
|
2026-05-18T14:01:11.877853+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112871877_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...
|
[{"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}]...
|
6088908589105147991
|
-1414059449518157871
|
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...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55307
|
1914
|
54
|
2026-05-18T14:01:05.840366+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112865840_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...
|
55306
|
NULL
|
NULL
|
NULL
|
|
55306
|
1914
|
53
|
2026-05-18T14:01:02.823546+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112862823_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
|
|
55305
|
1914
|
52
|
2026-05-18T14:00:59.818452+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112859818_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...
|
[{"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}]...
|
6088908589105147991
|
-1414059449518157871
|
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...
|
55304
|
NULL
|
NULL
|
NULL
|
|
55304
|
1914
|
51
|
2026-05-18T14:00:56.789284+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112856789_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...
|
[{"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}]...
|
8243381250999052583
|
-8204424741936591934
|
visual_change
|
hybrid
|
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
Firefox• 0FileEditViewHistoryBookmarksProfiles→ToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kovalik%40jiminny.com100% <78 • Mon 18 May 17:00:56)A05Galya DimitrovaNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:00 PM | [Platform] Refinement'1:47:23...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55303
|
1914
|
50
|
2026-05-18T14:00:53.752370+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112853752_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...
|
[{"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}]...
|
-4411325496289755485
|
-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...
|
55302
|
NULL
|
NULL
|
NULL
|
|
55302
|
1914
|
49
|
2026-05-18T14:00:50.721504+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112850721_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":"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}]...
|
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);
}
}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
55301
|
1914
|
48
|
2026-05-18T14:00:47.667776+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779112847667_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'...
|
[{"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}]...
|
-4047408223668449518
|
-8636777727364969024
|
visual_change
|
hybrid
|
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'
Firefox• 0FileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/cxs-eips-npt?authuser=lukas.kova100% C8 • Mon 18 May 17:00:4740jiminny.com5Galya DimitrovNikolay Yankov*Nikolay IvanovAneliya AngelovaLukas Kovalik5:00 PM | [Platform] Refinement ®1:47:14...
|
55300
|
NULL
|
NULL
|
NULL
|