|
49767
|
1770
|
12
|
2026-05-18T06:57:35.420434+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087455420_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProi PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpaateupporunityspectications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Modell• Midrate46 Y1Y6 APlavbackithemesM Plavbooks142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:D Playlists> M Postmarkpublic function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;public function getActivitvSearchido: int-...=public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56>UP trackina controller 1 tile, 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23l10.00=custom.loglaravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipedrive\versions\v1 \Api\PersonFieldsApi;use Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:T2122 Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 6tprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.26 616 usaaesnrivate arrav Sresults = 1:Nothina to showDally - Plauorm• om lemt100% 2.• Mon 18 May 9:57:35AskJiminnyReportActivityServiceTest ve Q+0 ..• Debugging PipedriveAnalvzedvendor/oinedrive/oipedrive/ulb/versions/v2Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:• TestPipedriveOfficialSdkCommand.php• TestPipedriveOfficialSdkCommand.php• TestCommand dockoO docker exec docker lamo 1 oho artisan iiminnv:test-oinedrive-official-sdk 192fles 176.28>Ask anvthina (*4L)+ &CodeSWE-1.6+16 -8+32 -8Run &e Skip2) Reject allAccept all090W Windsurf Toam.14-1/25 charc 1 line hreakllUTE.R'Po 4 spaces...
|
NULL
|
-6266624643009127699
|
NULL
|
click
|
ocr
|
NULL
|
PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProi PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpaateupporunityspectications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Modell• Midrate46 Y1Y6 APlavbackithemesM Plavbooks142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:D Playlists> M Postmarkpublic function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;public function getActivitvSearchido: int-...=public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56>UP trackina controller 1 tile, 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23l10.00=custom.loglaravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipedrive\versions\v1 \Api\PersonFieldsApi;use Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:T2122 Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 6tprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.26 616 usaaesnrivate arrav Sresults = 1:Nothina to showDally - Plauorm• om lemt100% 2.• Mon 18 May 9:57:35AskJiminnyReportActivityServiceTest ve Q+0 ..• Debugging PipedriveAnalvzedvendor/oinedrive/oipedrive/ulb/versions/v2Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:• TestPipedriveOfficialSdkCommand.php• TestPipedriveOfficialSdkCommand.php• TestCommand dockoO docker exec docker lamo 1 oho artisan iiminnv:test-oinedrive-official-sdk 192fles 176.28>Ask anvthina (*4L)+ &CodeSWE-1.6+16 -8+32 -8Run &e Skip2) Reject allAccept all090W Windsurf Toam.14-1/25 charc 1 line hreakllUTE.R'Po 4 spaces...
|
49761
|
NULL
|
NULL
|
NULL
|
|
49766
|
1769
|
34
|
2026-05-18T06:57:35.440152+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087455440_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
+FirefoxFileEditViewHistoryBookmarksProfilesToolsW +FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform - 8 m left→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)TớtMon 18 May 9:57T2 (SRD83 mi* PrO+ Atter XIE3 мCя(a Sche x© CursCost XOum xQ мcяo Pipt X8 JmO [URL_WITH_CREDENTIALS] 15 П ***=DeployedД лy-20880 (1 П ***=Upgrade BE Ibraries - MayMAINTENANCSваскlюяіE JY-19958•****=@Allow owner's role to beselected when setting up aUpgrade Python andIbraries - MayMAINTENANCESetup test coverage forProphet in Sonar|EMPROVEMENT OF OUR EFFICHINGTIn DevД 3y-2061315 = ®Deployed@ J-19951 1 0 ••=Improve Activity TypesuggestionsAUTO-DETEGTED AGTEVITY TYPBacklogP SY-204702 ..= 1Sepricated Gemini modeisDeployedЕ 3-202720 •+=|Sidekick SMS issueDeployedC PY-20091n •=€100% <478• Mon 18 May 9:57:35Ota=Steliyan GeorgievNikolay YankovNikolay Manoy cosAneliya Angelova9:57 AM | Daily - PlatformLukas Kovalik11:09...
|
NULL
|
8507021692605676010
|
NULL
|
click
|
ocr
|
NULL
|
+FirefoxFileEditViewHistoryBookmarksProfilesToolsW +FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform - 8 m left→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)TớtMon 18 May 9:57T2 (SRD83 mi* PrO+ Atter XIE3 мCя(a Sche x© CursCost XOum xQ мcяo Pipt X8 JmO [URL_WITH_CREDENTIALS] 15 П ***=DeployedД лy-20880 (1 П ***=Upgrade BE Ibraries - MayMAINTENANCSваскlюяіE JY-19958•****=@Allow owner's role to beselected when setting up aUpgrade Python andIbraries - MayMAINTENANCESetup test coverage forProphet in Sonar|EMPROVEMENT OF OUR EFFICHINGTIn DevД 3y-2061315 = ®Deployed@ J-19951 1 0 ••=Improve Activity TypesuggestionsAUTO-DETEGTED AGTEVITY TYPBacklogP SY-204702 ..= 1Sepricated Gemini modeisDeployedЕ 3-202720 •+=|Sidekick SMS issueDeployedC PY-20091n •=€100% <478• Mon 18 May 9:57:35Ota=Steliyan GeorgievNikolay YankovNikolay Manoy cosAneliya Angelova9:57 AM | Daily - PlatformLukas Kovalik11:09...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49768
|
1769
|
35
|
2026-05-18T06:57:38.153463+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087458153_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditDaily - Platform • 8 m leftViewHist FirefoxFileEditDaily - Platform • 8 m leftViewHistoryBookmarksProfilesToolsWindowHelp→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)EditMon 18 May 9:57YSRD83 mi* PrO+ Atter XIE3 мся(a Sche x© cuns x* Oa xCost XOum xQ мcяo Pipt X8 Jm• [URL_WITH_CREDENTIALS] 15 П ***=DeployedД л-20880 П0 П •**=**Upgrade Python andIbraries - MayMAINTENANCISetup test coverage forProphet in SonarUpgrade BE Ibraries - MayMAINTENANCSваскlюяі© JY-19958•****=@Allow owner's role to beselected when setting up aEMPROVEMENT OF OUR EFFICHINGNIn DevД 3y-2061315 = ®Deployed7J7-190511 0 •00=Improve Activity TypesuggestionsAUTO-DETEGTED AGTIVITY TYPBacklogP JY-204702 ..= 1Sepricated Gemini modeisDeployed3-20272Sidekick SMS issueDeployedCE PY-20091n •*=€100% L28•Mon 18 May 9:57:37Steliyan GeorgievNikolay Manoy cooesNikolay YankovAneliya Angelova9:57 AM | Daily - PlatformLukas Kovalik• 11:12|...
|
NULL
|
2758611185191770635
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditDaily - Platform • 8 m leftViewHist FirefoxFileEditDaily - Platform • 8 m leftViewHistoryBookmarksProfilesToolsWindowHelp→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)EditMon 18 May 9:57YSRD83 mi* PrO+ Atter XIE3 мся(a Sche x© cuns x* Oa xCost XOum xQ мcяo Pipt X8 Jm• [URL_WITH_CREDENTIALS] 15 П ***=DeployedД л-20880 П0 П •**=**Upgrade Python andIbraries - MayMAINTENANCISetup test coverage forProphet in SonarUpgrade BE Ibraries - MayMAINTENANCSваскlюяі© JY-19958•****=@Allow owner's role to beselected when setting up aEMPROVEMENT OF OUR EFFICHINGNIn DevД 3y-2061315 = ®Deployed7J7-190511 0 •00=Improve Activity TypesuggestionsAUTO-DETEGTED AGTIVITY TYPBacklogP JY-204702 ..= 1Sepricated Gemini modeisDeployed3-20272Sidekick SMS issueDeployedCE PY-20091n •*=€100% L28•Mon 18 May 9:57:37Steliyan GeorgievNikolay Manoy cooesNikolay YankovAneliya Angelova9:57 AM | Daily - PlatformLukas Kovalik• 11:12|...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49769
|
1770
|
13
|
2026-05-18T06:57:40.648193+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087460648_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormINavicareCodeLaravelKeractorFV faVsco.js?° PhostormINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect vC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOS> C ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxes• Midrateclass AutomatedReport extends Model46 Y1Y6 AVPlavbackithemesM PlavbooksPlaylists> M Postmark142143144return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:18public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 161© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;T2122 0public function getActivitvSearchido: ?int-...=24 6t26 61public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filoc 8 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23lCode will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aao)$0#Daily - Platform - 8m left100% Sz. Mon 18 May 9:57:40AskJiminnyReportActivityServiceTest v+0 ..=custom.log=laravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmuse Jiminny Models\UserPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':onteated sraaintion e roat neiaien Pinatlive so Cotnat ie anatio E6 usaaesnrivate arrav Sresults = 1:Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.phpThouahts•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughts>Command docker• docker exec docker lamo 1 pho artisan iiminnv:test-oipedrive-official-sdk 19+7-7+16 -8+32 -8Ask anvthina (*4L)+ &codeSWE-1.62) Reject allAccept allO90Nothina to showW Windsurf Teams 161:1 UTF-8 P 4 spaces...
|
NULL
|
7586472238672552984
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhostormINavicareCodeLaravelKeractorFV faVsco.js?° PhostormINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect vC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOS> C ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxes• Midrateclass AutomatedReport extends Model46 Y1Y6 AVPlavbackithemesM PlavbooksPlaylists> M Postmark142143144return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:18public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 161© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;T2122 0public function getActivitvSearchido: ?int-...=24 6t26 61public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filoc 8 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23lCode will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aao)$0#Daily - Platform - 8m left100% Sz. Mon 18 May 9:57:40AskJiminnyReportActivityServiceTest v+0 ..=custom.log=laravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmuse Jiminny Models\UserPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':onteated sraaintion e roat neiaien Pinatlive so Cotnat ie anatio E6 usaaesnrivate arrav Sresults = 1:Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.phpThouahts•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughts>Command docker• docker exec docker lamo 1 pho artisan iiminnv:test-oipedrive-official-sdk 19+7-7+16 -8+32 -8Ask anvthina (*4L)+ &codeSWE-1.62) Reject allAccept allO90Nothina to showW Windsurf Teams 161:1 UTF-8 P 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49770
|
1769
|
36
|
2026-05-18T06:57:42.280756+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087462280_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
7615519264991870121
|
-1337231682577703274
|
app_switch
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
+Firefox Meet - Daily - Platform
Close tab
New Tab
+FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)TớtT2 (SRD83 mi* PrO+ Atter XI3 мСР(a Sche x© Curs |Cost XQ мсяo Pipt Xhttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/3788C Projects23 SSHE DatadogC DevPlatform Team %.Q Search board8800018Epic ~TypeQuick filtersMADTOKONotify the user if aMCP > Enabie users to get(HubSpot) Optimise CRMAJ REPORTSBacklog[ JY-206763 ..=©JIMENNY MCP CONNECTORIn Dev( JY-208339 ***=wowcehtootteuierJIMINNY MCP CONNECTORvoob KorД л-20046 35 12 •**= Ohubspot accounts/contactsCLATFORM STARTUTYIn QA0 -20725 15 1 •***=Notify the user if a SS isdeleted but is used in AJReportAJREPORTSBacklogA JY-20615|2.5 •000 =MCP > Enable users to getsustor ocais and tneildetallsJIMINNY MOP CONNECTORIn DevД Jy-20835 20 0 ***=Upgrade to PHP 8.5PHP B.S UPGRADEReady for QA© л-n0n 15 1l ***= O**Upgrade Python andIbraries - MayUpgrade BE Ibraries - MayAllow owner's role beMAINTENANCSMAINTENANCEselected when setting up atrial eваскlюяіEMPROVEMENT OF OUR ERFICHINGYE JY-19958•****=@In DevД Jy-2061315 = ®amprove Acuvity lypelsuggestionsAUTO-DETEGTED AGTIVITY TYPBacklogP JY-204702 ..= 19:57 AM | Daily - PlatformDaily - Platform - 8 m left100% <478• Mon 18 May 9:57:41=O caGroup: QueriesAJ Panorama for Call|Scoring in ODAUTOMATED AI SCORINGDeployedД 3y-20301 /05[Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД лy-20880 (1 П ***=Setup test coverage forProphet in SonarDeployed7J7-990511 0•00=Sepricated Gemini modeisDeployed₴ 3-202720 •.=Sidekick SMS issueDeployedCE PY-20091n •=€Mon 18 May 9:57L Al BookmarksSteliyan GeorgievNikolay YankovNikolay vanoy cousAneliya AngelovaLukas Kovalik• 11:16...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49771
|
1770
|
14
|
2026-05-18T06:57:45.952992+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087465952_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
774314252020369718
|
955665125233942166
|
click
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpaateupporunityspectications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Modell• Midrate46 Y1Y6 AVPlavbackithemesM Plavbooks142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_ JIMINNY:D Playlists> M Postmark18public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;T2122 Dpublic function getActivitvSearchido: int-...=24 6t26 61public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder callc 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56>UP trackina controller 1 tile, 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9:2310.00Dally - Plauorm• om lemt100% S2• Mon 18 May 9:57:45)AskJiminnyReportActivityServiceTest v+0 ..=custom.log=laravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmuse Jiminny Models\UserPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.nontecter Stasasinzinn + LTest néficial Pinefaive snk Cninefaive/ninedoive) with e6 usaaesnrivate arrav Sresults = 1:Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.php•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughts>Command docker• docker exec docker lamp 1pho artisan liminnv:test-oipedrive-official-sok 19+7 -7+16 -8+32 -8Ask anvthina (*4L)+ &CodeSWE-1.62) Reject allAccept all090Nothina to showW Windsurf Teams 161:1 UTF-8 Po 4 spaces...
|
49769
|
NULL
|
NULL
|
NULL
|
|
49772
|
1769
|
37
|
2026-05-18T06:57:48.013241+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087468013_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
6106278563745808422
|
-3642507338288554346
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
FirefoxFileTools Meet - Daily - Platform
Close tab
FirefoxFileToolsWindowDaily - Platform - 8 m left100% <478• Mon 18 May 9:57:47EditViewHistoryBookmarksProfiles→Helpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)=+18Platform Team 8.Q Search boardKADTDOKONotify the user d adeieted but is used in AJ...AJREPORTSBacklog[Д JY-206763 •00=Notify the user if a SS isdeieted but is used in AJReportAJ REPORTSBacklogД JY-20615Upgrade BE Ibraries - MayMAINTENANGSHacoeE JY-19958AneovencvilsuggestionsAUTO-OITICTED ACTIVITY TYPP SY-204102 **** =YSRD XxJm xE3 ProM+Ate X2 Мo x[l Sche x Cun xhttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613L Projects•08 NED 0 G t caude OcckaSentry *xD Lass00P JI-1ESS1 1 JT-201SAllow owner's role to be selected when setting up a trial~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Impiementations to select the role of the owner when setting up a trialo put the field bellow the Owner emall field• single select•this opton shoulont appear wnen eotting an organisaboeSubtasksAesuetsKLinked work itemsAod linked work iuetnoodcomtneSuggest a reply.Status upoate..Thanks...Mon 18 May 9:57L) Al BookmarxsIn DevI Improve Story~ DetailsAssignee@ Lutas KovalikAssign to meReporter2 Galya DimtrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissDeveic omenOpen with VS Code|IJ Create branch4 Create commitComponentsPlatformD D DUGroup: QueriesAJ Panorama for CallScoring in ODAUTOMATED AI SCORINGД 3-20301 05(Deadline 25 May] Migratedepricated Gemini 3.1 FlashDeployedд 37-20880 0 11 ***=Setup test coverage forProphet in Sonar©л-ms 18 0 *=E 39-202720 • = *Sidekick SMS issueDeployedXE P1-20001n • =€Steliyan GeorgievNikolay YankovNikolay lyanoy coosAneliya Angelova9:57 AM | Daily - PlatformTurn on microphone (% + d)..•Lukas Kovalik• 11:22|...
|
49770
|
NULL
|
NULL
|
NULL
|
|
49773
|
1770
|
15
|
2026-05-18T06:57:51.474883+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087471474_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
7615519264991870121
|
-1337231682577703274
|
click
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Pnostorm Meet - Daily - Platform
Close tab
New Tab
PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpaateupporunityspectications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Modell• Midrate46 Y1Y6 AVPlavbackithemesM Plavbooks142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_ JIMINNY:D Playlists> M Postmark18public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;T2122 Dpublic function getActivitvSearchido: int-...=24 6t26 61public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder callc 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56>UP trackina controller 1 tile, 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9:2310.00Dally - Plauorm• om lemt100% S2• Mon 18 May 9:57:51AskJiminnyReportActivityServiceTest v+0 ..=custom.log=laravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmuse Jiminny Models\UserPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.nontecter Stasasinzinn + LTest néficial Pinefaive snk Cninefaive/ninedoive) with e6 usaaesnrivate arrav Sresults = 1:Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.php•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughts>Command docker• docker exec docker lamp 1pho artisan liminnv:test-oipedrive-official-sok 19+7 -7+16 -8+32 -8Ask anvthina (*4L)+ &CodeSWE-1.62) Reject allAccept all090Nothina to showW Windsurf Teams 161:1 UTF-8 Po 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49774
|
1769
|
38
|
2026-05-18T06:57:54.010380+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087474010_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFilelEditViewHistoryBookmarksProfilesToolsW FirefoxFilelEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 8 m left100% L8• Mon 18 May 9:57:53meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)YISRD X83 ХтE3 ProкC AttexMo xEa Sche *© Cursnny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613500008U Epaton 0 ©Cos XрмоxоPpE x5m xO cHAwecaere18Platform Team %Q Searcn poaraMAOTYOKOEWNotify the user i adeieted but is used in AJ..AJREPORTSBackiogC Jy-20676aaee-Notify the user if a SS isdeletea dut is usea in AJNeweetAJREPOKTSBackiogC) Jy-2061525 •000 =Upgrade BE lbraries - MayMAINTENANCSsuggestionsAUTO-OETECTED ACTEVITY TYPGJy-204102 .0009 J1-12S1U J-2019Allow owner's role to be selected when setting up a trial~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trial|put the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single selectthis opton shoulont appear wnien eoiting an organisabonWhon the oonieewkouewwthewdoweATeesorSubtasksAdd subtaskLinked work itemsAO0 tinked Work ibewnoo d conierisSuggest a reply.Thanks…-***In DevI Improve StoryDetailsAssignee@ Lukas KovalikAssign to me2 Gaya DimtrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDevelc omenOpen with VS Code.I Create brasch4 Create commit.|ComponentsPlatformGroup: QuenesAJ Panorama for CallScoring m ouAUтоMATED AL SCORINGД J-20301 05[Deadline 25 May] Migratedepricated Gemini 3.1 FlashDeployedД Jy-20880 |8 () *** =Setup test coverage forProphet in Sonar937-1951 1E 31-20272SicenocK SMS issueDeployedC Pr-20001.Steliyan GeorgievNikolay Yankov9:57 AM | Daily - PlatformLukas Kovalik• 11:28|...
|
NULL
|
2881830351494099405
|
NULL
|
click
|
ocr
|
NULL
|
FirefoxFilelEditViewHistoryBookmarksProfilesToolsW FirefoxFilelEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 8 m left100% L8• Mon 18 May 9:57:53meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)YISRD X83 ХтE3 ProкC AttexMo xEa Sche *© Cursnny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613500008U Epaton 0 ©Cos XрмоxоPpE x5m xO cHAwecaere18Platform Team %Q Searcn poaraMAOTYOKOEWNotify the user i adeieted but is used in AJ..AJREPORTSBackiogC Jy-20676aaee-Notify the user if a SS isdeletea dut is usea in AJNeweetAJREPOKTSBackiogC) Jy-2061525 •000 =Upgrade BE lbraries - MayMAINTENANCSsuggestionsAUTO-OETECTED ACTEVITY TYPGJy-204102 .0009 J1-12S1U J-2019Allow owner's role to be selected when setting up a trial~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trial|put the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single selectthis opton shoulont appear wnien eoiting an organisabonWhon the oonieewkouewwthewdoweATeesorSubtasksAdd subtaskLinked work itemsAO0 tinked Work ibewnoo d conierisSuggest a reply.Thanks…-***In DevI Improve StoryDetailsAssignee@ Lukas KovalikAssign to me2 Gaya DimtrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDevelc omenOpen with VS Code.I Create brasch4 Create commit.|ComponentsPlatformGroup: QuenesAJ Panorama for CallScoring m ouAUтоMATED AL SCORINGД J-20301 05[Deadline 25 May] Migratedepricated Gemini 3.1 FlashDeployedД Jy-20880 |8 () *** =Setup test coverage forProphet in Sonar937-1951 1E 31-20272SicenocK SMS issueDeployedC Pr-20001.Steliyan GeorgievNikolay Yankov9:57 AM | Daily - PlatformLukas Kovalik• 11:28|...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49775
|
1770
|
16
|
2026-05-18T06:57:57.261346+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087477261_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormINavicareCodeLaravelKeractorFV faVsco.js?° PhostormINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect vC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpaateupporunityspectications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohgC) CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Modell• Midrate46 y1Y6 APlavbackithemesM PlavbooksPlaylists> M Postmark142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 161© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;public function getActivitvSearchido: ?int-...=public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder callc 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filoc 8 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23lCode will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aaol=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU18T2122 024 6t26 61use Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AccLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends CommandAccept Rejectprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':6 usagesprivata aaray edngsylt Accept File g- X Reject File t*a+ 20f2 files →Nothina to show$0#Daily - Platform - 8 m left100% Sz• Mon 18 May 9:57:57AskJiminnyReportActivityServiceTest v+0 ..Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.php•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughts>Command docker• docker exec docker lamo 1 pho artisan iiminnv:test-oipedrive-official-sdk 19+7-7+16 -8+32 -8Ask anvthina (*4L)+ &codeSWE-1.62) Reject allAccept all090W Windsurf Teams 161:1 UTF-8 P 4 spaces...
|
NULL
|
-667855940121658268
|
NULL
|
click
|
ocr
|
NULL
|
PhostormINavicareCodeLaravelKeractorFV faVsco.js?° PhostormINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect vC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpaateupporunityspectications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohgC) CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Modell• Midrate46 y1Y6 APlavbackithemesM PlavbooksPlaylists> M Postmark142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 161© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;public function getActivitvSearchido: ?int-...=public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder callc 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filoc 8 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23lCode will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aaol=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU18T2122 024 6t26 61use Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AccLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends CommandAccept Rejectprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':6 usagesprivata aaray edngsylt Accept File g- X Reject File t*a+ 20f2 files →Nothina to show$0#Daily - Platform - 8 m left100% Sz• Mon 18 May 9:57:57AskJiminnyReportActivityServiceTest v+0 ..Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.php•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughts>Command docker• docker exec docker lamo 1 pho artisan iiminnv:test-oipedrive-official-sdk 19+7-7+16 -8+32 -8Ask anvthina (*4L)+ &codeSWE-1.62) Reject allAccept all090W Windsurf Teams 161:1 UTF-8 P 4 spaces...
|
49773
|
NULL
|
NULL
|
NULL
|
|
49776
|
1769
|
39
|
2026-05-18T06:57:59.299974+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087479299_m1.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFilelEditViewHistoryBookmarksProfilesToolsW FirefoxFilelEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 8 m left100% L2• Mon 18 May 9:57:58meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA518Platform Team %.Q Search boardKAOTOHOWNotify the user i adeleted but is used in AJ....AJ REPORTSBacklogД JY-206763 9000 =Notify the user it a SS isdeleted but is used in AJReportAJREPORTSBacklogR JY-206157%000Upgrade BE Ibraries - MayMAINTENANCEE JY-19958Improve Activity TypesuggestionsAUTO-DETEGTED AGTIVITY TYPBacklogP JY-204102 as00=SRD XxJimE3 Pron( Alte: x | EB MCP x [l Sche x ® Cun x1* cix x Cos: x 0 Jmi x Q MCP x Pipe x Jmi x O Cahttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613D Projects8009JI-122SS1 1 JTZ901SAllow owner's role to be selected when setting up a trial~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialo put the field bellow the Owner emall field• single select• this opton shoulont appear wnen eotting an organisaboeWhen the dhieewweuewwethedoweATewetorSubtasksAdd subtaskLinked work itemsAOd linkec Work ibernood comionsSuggest a replyStatus update...Thanks.L DerIn DevI Improve Story~ DetailsAssignee@ Lukas KovalikAssign to me& Gaya DimtrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissDevelo ottenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformGroup: QueriesAJ Panorama for CallScoring in ODAUTOMATED AL ECORINGDeployedJy-20301 0S(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД 37-20880 0 11 ***=Setup test coverage forProphet in SonarDeployedE3 J-19951 1 0 •00=DeployedE Jy-20272Sidekick SMS issueDeployedC Pr-2000111 ***=1La Ai BockmarxsSteliyan GeorgievNikolay Yankov9:57 AM | Daily - PlatformLukas Kovalik• 11:33|...
|
NULL
|
-3904080891129387065
|
NULL
|
click
|
ocr
|
NULL
|
FirefoxFilelEditViewHistoryBookmarksProfilesToolsW FirefoxFilelEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 8 m left100% L2• Mon 18 May 9:57:58meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA518Platform Team %.Q Search boardKAOTOHOWNotify the user i adeleted but is used in AJ....AJ REPORTSBacklogД JY-206763 9000 =Notify the user it a SS isdeleted but is used in AJReportAJREPORTSBacklogR JY-206157%000Upgrade BE Ibraries - MayMAINTENANCEE JY-19958Improve Activity TypesuggestionsAUTO-DETEGTED AGTIVITY TYPBacklogP JY-204102 as00=SRD XxJimE3 Pron( Alte: x | EB MCP x [l Sche x ® Cun x1* cix x Cos: x 0 Jmi x Q MCP x Pipe x Jmi x O Cahttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613D Projects8009JI-122SS1 1 JTZ901SAllow owner's role to be selected when setting up a trial~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialo put the field bellow the Owner emall field• single select• this opton shoulont appear wnen eotting an organisaboeWhen the dhieewweuewwethedoweATewetorSubtasksAdd subtaskLinked work itemsAOd linkec Work ibernood comionsSuggest a replyStatus update...Thanks.L DerIn DevI Improve Story~ DetailsAssignee@ Lukas KovalikAssign to me& Gaya DimtrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissDevelo ottenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformGroup: QueriesAJ Panorama for CallScoring in ODAUTOMATED AL ECORINGDeployedJy-20301 0S(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД 37-20880 0 11 ***=Setup test coverage forProphet in SonarDeployedE3 J-19951 1 0 •00=DeployedE Jy-20272Sidekick SMS issueDeployedC Pr-2000111 ***=1La Ai BockmarxsSteliyan GeorgievNikolay Yankov9:57 AM | Daily - PlatformLukas Kovalik• 11:33|...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49777
|
1770
|
17
|
2026-05-18T06:58:02.185693+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087482185_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormVIewINavicareCodeLaravelRefactorFV faVsco. PhpStormVIewINavicareCodeLaravelRefactorFV faVsco.js?° pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammeradata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Deallnsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ongc) IntearationApp/Service.phpC) CreateSelfCoachedEvent.phpD DTOSC Elasticsearch©) CreateCommentedEvent.php© PlanhatActivityListener.php(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Mode]• Midrate46V1Y6 APlavbackithemes141return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:M PlavbooksM Plavlists> M Postmark144public function isExpired: boolf...}m PronhetAv M Renorto© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16@)AutomatedReoortsSendcommano.on© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php>07 Slack172>C Teams>C TracksC Transcription177>C TwilioC Users> M Vocabularv> MZoompublic function canExecute@: boolf...;public function getActivitySearchid@: 2int{...}public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...16 usagespublic function getSavedSearch: ?Searcht...16 usagespublic function getAskAnythingPrompt: ?AskAnythingPrompt{...}C) Command.oho© CreateDatabaseUsers.ohpC)DatabaseTiableCount.oho@ DeleteOldAiCrmNotesCommand.ohpCDeleteS?Leftoverscommand.ohn@ DevPostmanCommand.phpC) DiarizeViaAiParticinantldentificationComi©EncryptTokensCommand.php(C EnaadementStatsRedenerateCommand.r( FeatureflaasHelner ohr186187188189190191192196197* Get the ID of the automated report.* @return intpublic function getid@: intf...}* Get the UUID of the automated report.* dreturn string© FixCrossTenant|ssues.php@ FluchRolesPermissionsCache.php© GeneratelnternalWebhookToken.php0 GrounSetDefaultLanquageCommand.phcpublic function getUuidO: strings...;(@) HolnerTruncateCoachinaTlables.ono* Get the team T0 of the automated renortiHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes adol=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]= 2022024 6t26 6t32 61A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept Renectuse FepeurevelverstunslveiapeActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions v2 Ani ActivitiecAni.use rrpearive verszons Ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipearive versions vz Ap1 Personr1elasAp1*use Pipedrive versions vz Ap1 PersonsAp1use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamtd-':nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive) with exisnrivate arrav Sresults = 1:nnivate EncnuntedtokenManaden CtokenManagen.public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int SteamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.X Reject File 02Sthis->infod strino: 'Test 2• Basic CRUD Oberations')3#Daily - Platform • 7 m left100% Lz• • Mon 18 May 9:58:02AskJiminnyReportActivityServiceTest vamn 1oho artisan iiminnv.tect-ninedrive-official-sdk 19W Windsurf Teams 161:1 UTF-8 P 4 spaces...
|
NULL
|
-4010286145728363388
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormVIewINavicareCodeLaravelRefactorFV faVsco. PhpStormVIewINavicareCodeLaravelRefactorFV faVsco.js?° pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ong© SyncPlanhat.php©syncleammeradata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Deallnsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ongc) IntearationApp/Service.phpC) CreateSelfCoachedEvent.phpD DTOSC Elasticsearch©) CreateCommentedEvent.php© PlanhatActivityListener.php(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Mode]• Midrate46V1Y6 APlavbackithemes141return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:M PlavbooksM Plavlists> M Postmark144public function isExpired: boolf...}m PronhetAv M Renorto© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16@)AutomatedReoortsSendcommano.on© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php>07 Slack172>C Teams>C TracksC Transcription177>C TwilioC Users> M Vocabularv> MZoompublic function canExecute@: boolf...;public function getActivitySearchid@: 2int{...}public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...16 usagespublic function getSavedSearch: ?Searcht...16 usagespublic function getAskAnythingPrompt: ?AskAnythingPrompt{...}C) Command.oho© CreateDatabaseUsers.ohpC)DatabaseTiableCount.oho@ DeleteOldAiCrmNotesCommand.ohpCDeleteS?Leftoverscommand.ohn@ DevPostmanCommand.phpC) DiarizeViaAiParticinantldentificationComi©EncryptTokensCommand.php(C EnaadementStatsRedenerateCommand.r( FeatureflaasHelner ohr186187188189190191192196197* Get the ID of the automated report.* @return intpublic function getid@: intf...}* Get the UUID of the automated report.* dreturn string© FixCrossTenant|ssues.php@ FluchRolesPermissionsCache.php© GeneratelnternalWebhookToken.php0 GrounSetDefaultLanquageCommand.phcpublic function getUuidO: strings...;(@) HolnerTruncateCoachinaTlables.ono* Get the team T0 of the automated renortiHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes adol=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]= 2022024 6t26 6t32 61A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept Renectuse FepeurevelverstunslveiapeActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions v2 Ani ActivitiecAni.use rrpearive verszons Ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipearive versions vz Ap1 Personr1elasAp1*use Pipedrive versions vz Ap1 PersonsAp1use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamtd-':nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive) with exisnrivate arrav Sresults = 1:nnivate EncnuntedtokenManaden CtokenManagen.public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int SteamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.X Reject File 02Sthis->infod strino: 'Test 2• Basic CRUD Oberations')3#Daily - Platform • 7 m left100% Lz• • Mon 18 May 9:58:02AskJiminnyReportActivityServiceTest vamn 1oho artisan iiminnv.tect-ninedrive-official-sdk 19W Windsurf Teams 161:1 UTF-8 P 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49778
|
1769
|
40
|
2026-05-18T06:58:03.518297+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087483518_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp•Daily - Platform • 7 m left100%8• Mon 18 May 9:58:03meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)181:Platform Team 2.Q Search boardKAOTTOK OWNotity the user it adeleted but is used in AJ...AJREPORTSBacklogJY-206763 9aa0=deleted but is used in AJReportAJRIPORTSBacklogД JY-206157%%00Upgrade BE Ibraries - MayMAINTENANCSKacoeE JY-19958suggestionsAUTO-DETEGTED AGTIVITY TYРОCoekoeP JY-204702 a000=SRD X83 JimliE3 PronAtte: x | EB MC x [l Sche x ® Cun x1* Cia x Cost x ® Jmi x Q MCP X 3 Pipe xSumxCakhttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613C Projects•08BEDt 0 © % Caude O CrckaAseky X D lacD Der DUPJ1-122SS1 1 JT-X901SAllow owner's role to be selected when setting up a trialIn DevvI7 Improve Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.Assignee@ Lukas KovalikAssign to me• allow Implementations to select the role of the owner when setting up a trial|o put the fieid bellow the Owner emall fieldE Galya Dimitrova• single select•this option shoulont appear wnien eoiting an organisaboeWhen the ChrieeweuewethedooeATeestonQuick start developmentUnk this work ikem to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAdd subtaskDeveic omenLinked work itemsAod linkec work iberOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnood comirnsSueeToeeSuggest a reply-Status update...Thanks...Group: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGDeployedwy-20301 /05(Deadiine 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 0 П1 ***=Setup test coverage forProphet in SonarE3 J-19051 |1 0 •00=Е3 Jy-20272Sidekick SMS issueDeployed0 P1-20001n •n =€Mon 18 May 9:58La Al BockmarksNikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 11:37...
|
NULL
|
7579186294491275638
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp•Daily - Platform • 7 m left100%8• Mon 18 May 9:58:03meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)181:Platform Team 2.Q Search boardKAOTTOK OWNotity the user it adeleted but is used in AJ...AJREPORTSBacklogJY-206763 9aa0=deleted but is used in AJReportAJRIPORTSBacklogД JY-206157%%00Upgrade BE Ibraries - MayMAINTENANCSKacoeE JY-19958suggestionsAUTO-DETEGTED AGTIVITY TYРОCoekoeP JY-204702 a000=SRD X83 JimliE3 PronAtte: x | EB MC x [l Sche x ® Cun x1* Cia x Cost x ® Jmi x Q MCP X 3 Pipe xSumxCakhttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613C Projects•08BEDt 0 © % Caude O CrckaAseky X D lacD Der DUPJ1-122SS1 1 JT-X901SAllow owner's role to be selected when setting up a trialIn DevvI7 Improve Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.Assignee@ Lukas KovalikAssign to me• allow Implementations to select the role of the owner when setting up a trial|o put the fieid bellow the Owner emall fieldE Galya Dimitrova• single select•this option shoulont appear wnien eoiting an organisaboeWhen the ChrieeweuewethedooeATeestonQuick start developmentUnk this work ikem to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAdd subtaskDeveic omenLinked work itemsAod linkec work iberOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnood comirnsSueeToeeSuggest a reply-Status update...Thanks...Group: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGDeployedwy-20301 /05(Deadiine 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 0 П1 ***=Setup test coverage forProphet in SonarE3 J-19051 |1 0 •00=Е3 Jy-20272Sidekick SMS issueDeployed0 P1-20001n •n =€Mon 18 May 9:58La Al BockmarksNikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 11:37...
|
49776
|
NULL
|
NULL
|
NULL
|
|
49779
|
1770
|
18
|
2026-05-18T06:58:06.480442+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087486480_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.05618351,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
7962651264686056251
|
-7483856360197085818
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
PhpStormVIewINavicareCodeLaravelRefactorFV faVsco.js?° pipedrive-sdk-poc vProiect vConvertLeadActivities.php© DeleteScheduledUserActivitiesForinsightNotifyCrmOwnerDisconnectedListener.plYc) NotrvCrmuserDisconnecteaListener.ong© SetDefaultAvatarListener.phpcreatenuagecreatedevent.ong© CreateActivityAddedToPlaylistEvent.php© PlaybackController.phgOsetupediendarsync.onp© SetupMailSync.php© Syncintercom.php© SyncPlanhat.php© SyncUserPilot.php© ValidateSendingMessage.php© ValidateSendingNotification.php> [ WebhookE.aitkeep© AutomatedReportskepository.png© RequestGenerateReportJob.phpclass AutomatedReport extends Modeu142143144145return Sthis->gettvoeo === AutomatedReportsService::TYPE ASK JIMINNY:public function isExpired: boolt...(c) ChanceloccontexCorrelationid.ono> [ Mail152161public function canExecute: boolf...}> D MсD0 Modelspublic function getActivitySearchId: ?int{...}ActivityMAipublic function getAskAnythingPromptId: ?int{...}AskAnythingM Calendarpublic function getExpiresAtO: ?Carbonf...}n Connectionn Contracts16 usagesv 1Cmmpublic function getSavedSearch: ?Search{...}© BusinessProcess.php© Configuration.php(c) ContactRole nhn16 usagespublic function getAskAnvthingPrompt@: 2AskAnvthingPromot{...}C) Fiold nhr© FieldData.phpc) FieldValue.ong© Layout.phc© LayoutEntity.php© Log.php* Get the id of the automated renort.* dreturn intc Pronlle.onp© RecordType.phpnubilic function detiidos intc) SyncBatch.php> C ElasticSearch* Get the WUTD of the automated renort.w FeatureOpportunity0 Participant* @return stringPlavoack themepublic function getUuid(): string{...}PlavlistScorecardWebhook/*** Get the team ID of the automated report.(C) Account.oho@ Activitv.oho.* dreturn int(C) Address.ono(c) A Promnt nhrpublic function getTeamIdo: intf...}(c) AutomatedRenort nhr(C) AutomatedRenortRecult nhn216217(C) Calendar nhn* Get the tupe of the automated renort( Calllmnort nhnHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes adol#Daily - Platform • 7 m left100% Lz. Mon 18 May 9:58:06U AskJiminnyReportActivityServiceTest v# console [PKol)© TestPipedriveOfficialSdkCommand.php X © Kernel.php© SyncPlanhat.phpAcuvityLeadconvertea.onpc) Automatedreport.ono xm 6×1×6AY= custom.logA SF [jiminny@localhost]A console (slAGINe4 HS_local jiminny@localhost]A console [EU]use Jiminny Models\Teamuse Jiminny Modelsluseryuse Pinedrive versions vi Ao1 ActvItlesAD1.use Pivedrive versions vi Aoi Activitvsieldsaosuse Pinedrive versions vi Ani DealSieldsAni:Acceрt kejeсиsions\v1\Api\PersonFieldsApi;useuse Pipedrive versions.vz apt accrvicresapl,use Pipedrive\versions\v2\Api\ActivityFieldsApiuse ripedrive verszonsive aptlueatrzeLasapt,use ripearive verszons ve Ap1 UeaLsao1use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipedrive versions\v2\Api \PersonsApi:use Pipedrive versions vz contiquration,class TestPipedrive0fficialSdkCommand extends Commandprotected Ssiqnature ="1iminnv:test-oipedrive-official-sok <teamid'…protected Sdescrintion = "Test official Pipedrive SDK (oipedrive/oipedrive) with existing OAuth tokens':private arrav Sresults = Mprivate EncryptedTokenManager $tokenManager;public function __construct(EncryptedTokenManager $tokenManager)Sthic-stokenManaden = StokenManaden•public function handle: intf...}private function runTests(int SteamId): voidf...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}private function testBasiccruddperationsSocialAccount SsocialAccount: vo1d$this->info( string: 'Test 2: Basic CRUD Qperatzonad)2Accept File *~ X Reject File ta€ + 2 of 2 files →W Windsurf Toams 161-1UTF.8Po 4 spaces...
|
49777
|
NULL
|
NULL
|
NULL
|
|
49780
|
1769
|
41
|
2026-05-18T06:58:08.216211+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087488216_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
4013489942575271730
|
-7483500116281160310
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
FirefoxFileEditViewHistoryBookmarksProfilesTools|WindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:07meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOKOEWNotify the user it awnotat0omdeieted but is used in AJ...AJ REPORTSBacklogR Jy-206763 sas0=deleted but is used in AJnewetAJRIPORTSBacklogД JY-206157%00.Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroweeeviisuggestionsAUTO-DETEGTED AGTIVITY TYРОDockoeP JY-204702 •000=8• Mon 18 May 9:58YSRD X83 AmiE3 PronAlte: x | EB MCP x [ Sche x Cun x | * Cuu x COs: x 0 Umi x Q MCP X 0 PipE x Jmi x | Calehttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613D Hrojects08NEDtd 0 © % Cus O CrckaAserty X D lascD Der9 J1-1225S1 1 JT-2901SAllow owner's role to be selected when setting up a trialIn Dev vI Improve StoryDetails~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.Assignee@ Lukas KovalikAssign to me• allow Implementations to select the role of the owner when setting up a trialput the field bellow the Owner emall fieldE Galya Dimitrova• single selectthis option shoulont appear wnen eotting an organisaboewhen he caieeweueethewdotweATeskonQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreSubtasksAdd subtaskLinked work itemsAod linkec work ibenDevelc omenQ Open with VS CodeIJ Create branch4 Create commitComponentsPlatformnoo d conteenisSuggest a reply.Status update...Thanks..Sub-ProductlAdd optionsL Al BockmarxsGroup: QueriesAJ Panorama for CallScoring in ODAUTOMATED AI SCORINGDeployedP J-20301 /05(Deadiine 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 1 П1 •**=Setup test coverage forProphet in SonarDeployedsepricated Gemini modeisЕ3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20091n •=€Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 11:42|...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49781
|
1770
|
19
|
2026-05-18T06:58:11.567314+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087491567_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormViewINavicareCodeLaravelRefactorWindowFV f PhpStormViewINavicareCodeLaravelRefactorWindowFV faVsco.js?° pipedrive-sdk-poc vProiect© DeleteScheduledUserActivitiesForinsightNotifyCrmOwnerDisconnectedListener.plC) NotitvCrmUserDisconnecteaListener.ong© SetDefaultAvatarListener.phpC) SetuoCalendarsync.ong© SetupMailSync.php© Syncintercom.php© SyncPlanhat.php© SyncUserPilot.php© ValidateSendingMessage.php© ValidateSendingNotification.php> [ WebhookE.gitkeep(c) ChanceloccontexCorrelationid.ono> [ MailconvertLeadActivitles.ongo syncriannat.ongcreaterlaybookcreatedevent.phgc) IntearationApp/Service.phpC) CreateSelfCoachedEvent.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohp© PlanhatActivityListener.php(C)AskAnvthinaPromotService.ohd(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv(C) AutomatedReportkesultonp(C) AutomatedRenort nhn Xclass AutomatedRenont extends Mode]46 Y1Y6 A> D MсDv M ModelsActivityMAi141142143144return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:public function isExpired: boolf...}AskAnythingM Calendarpublic function canExecute@: boolf...;n ConnectionN Contractspublic function getActivitySearchid@: 2int{...}v 1Cmm© BusinessProcess.php© Configuration.php© ContactRole.phpC) Fiold nhrpublic function getAskAnvthingPromptIdO: 2intf...}172nublic function aetExoiresAtO: 2Carhons...© FieldData.php© FieldValue.php© Layout.php© LayoutEntity.php© Log.php(c) Profile.pnp© RecordType.php© SyncBatch.php> C ElasticSearch16 usages177public function getSavedSearch: ?Searcht...16 usagespublic function getAskAnythingPrompt: ?AskAnythingPrompt{...}187188189* Get the ID of the automated report.w FeatureE Opportunitv0 Participant* @return intPlavoack themepublic function getid@: intf...}PlavlistScorecardM Webhook197* Get the UUID of the automated report.(C) Account.oho@ Activitv.nho.* dreturn string(C) Address.ono(c) A Promnt nhrpublic function getUuidO: strings...;(c) AutomatedRenort nhr(C) AutomatedRenortRecult nhn(C) Calendar nhn( Calllmnort nhnlelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes adol* Get the team T0 of the automated renorti=custom.loglaravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]= 2022024 6t26 6t32 61A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipearive versions vz Ap1 Personr1elasAp1*use Pipearive versions vz Ap1 PersonsAp1use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamtd-':nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive) with exisnrivate arrav Sresults = 1:nnivate EncnuntedtokenManaden CtokenManagen.public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int SteamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usadeprivate function testBasicCrudOperations(SocialAccount $socialAccount): voidX Reject Flle :Sthis->infod strino: 'Test 2• Basic CRUD Oberations')3$0Daily - Platform • 7 m left100% L2. Mon 18 May 9:58:11AskJiminnyReportActivityServiceTest vCommand dockerO docker exec docker_lamp_1 php artisan jiminny:test-pipedrive-official-sdk 192 files +76-28>Ask anvthing (&4-DW Windsurf Teams 161:1 UTF-8 P 4 spaces...
|
NULL
|
-6187445209855203359
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormViewINavicareCodeLaravelRefactorWindowFV f PhpStormViewINavicareCodeLaravelRefactorWindowFV faVsco.js?° pipedrive-sdk-poc vProiect© DeleteScheduledUserActivitiesForinsightNotifyCrmOwnerDisconnectedListener.plC) NotitvCrmUserDisconnecteaListener.ong© SetDefaultAvatarListener.phpC) SetuoCalendarsync.ong© SetupMailSync.php© Syncintercom.php© SyncPlanhat.php© SyncUserPilot.php© ValidateSendingMessage.php© ValidateSendingNotification.php> [ WebhookE.gitkeep(c) ChanceloccontexCorrelationid.ono> [ MailconvertLeadActivitles.ongo syncriannat.ongcreaterlaybookcreatedevent.phgc) IntearationApp/Service.phpC) CreateSelfCoachedEvent.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohp© PlanhatActivityListener.php(C)AskAnvthinaPromotService.ohd(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv(C) AutomatedReportkesultonp(C) AutomatedRenort nhn Xclass AutomatedRenont extends Mode]46 Y1Y6 A> D MсDv M ModelsActivityMAi141142143144return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:public function isExpired: boolf...}AskAnythingM Calendarpublic function canExecute@: boolf...;n ConnectionN Contractspublic function getActivitySearchid@: 2int{...}v 1Cmm© BusinessProcess.php© Configuration.php© ContactRole.phpC) Fiold nhrpublic function getAskAnvthingPromptIdO: 2intf...}172nublic function aetExoiresAtO: 2Carhons...© FieldData.php© FieldValue.php© Layout.php© LayoutEntity.php© Log.php(c) Profile.pnp© RecordType.php© SyncBatch.php> C ElasticSearch16 usages177public function getSavedSearch: ?Searcht...16 usagespublic function getAskAnythingPrompt: ?AskAnythingPrompt{...}187188189* Get the ID of the automated report.w FeatureE Opportunitv0 Participant* @return intPlavoack themepublic function getid@: intf...}PlavlistScorecardM Webhook197* Get the UUID of the automated report.(C) Account.oho@ Activitv.nho.* dreturn string(C) Address.ono(c) A Promnt nhrpublic function getUuidO: strings...;(c) AutomatedRenort nhr(C) AutomatedRenortRecult nhn(C) Calendar nhn( Calllmnort nhnlelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes adol* Get the team T0 of the automated renorti=custom.loglaravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]= 2022024 6t26 6t32 61A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipearive versions vz Ap1 Personr1elasAp1*use Pipearive versions vz Ap1 PersonsAp1use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamtd-':nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive) with exisnrivate arrav Sresults = 1:nnivate EncnuntedtokenManaden CtokenManagen.public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int SteamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usadeprivate function testBasicCrudOperations(SocialAccount $socialAccount): voidX Reject Flle :Sthis->infod strino: 'Test 2• Basic CRUD Oberations')3$0Daily - Platform • 7 m left100% L2. Mon 18 May 9:58:11AskJiminnyReportActivityServiceTest vCommand dockerO docker exec docker_lamp_1 php artisan jiminny:test-pipedrive-official-sdk 192 files +76-28>Ask anvthing (&4-DW Windsurf Teams 161:1 UTF-8 P 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49782
|
1770
|
20
|
2026-05-18T06:58:16.828706+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087496828_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.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
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
PhpStormViewINavicareCode Project: faVsco.js, menu
PhpStormViewINavicareCodeLaravelRefactorTOOISWindowFV faVsco.js?° pipedrive-sdk-pocProiect vC ActivityController.ongD Contractsv DCrmC) ConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php© businessProcess.ongcontiguration.pnpcreatePlaybookcreatedevent.ong©) salestorce/service.phpcontactkole.onoc) Field.php© FieldData.phpc) IntearationApp/Service.phpC) LeadConverted.ohgC) CreateSelfCoachedEvent.phpC) FieldValue.php© Layout.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohdC)LavoutEntitv.php@ Loa.ph(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv© Profile.php@ RecordTvpe.ohp© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyosnowanycranyrrompe/? tnowany crangrrom© SyncBatch.phpElasticSearchN Feature0186187* Get the ID of the automated reportlN OpportunitvIM ParticinantM PlavbackTheme* dreturn intD PlaylistD ScorecardN Wehhookpublic function getido: int....© Account.php© Activity.php© Address.phpC) APrompt.pnp198* Get the UUID of the automated report.• Greturn strinac Automaleckeport.ono© AutomatedReportResult.php© Calendar.php(e Colllmnort nhn201202public function getUuid: stringi...Local ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.29> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9:23Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aaol$0#Daily - Platform • 7 m left100% Sz. Mon 18 May 9:58:16AskJiminnyReportActivityServiceTest v+0 ..=custom.log=laravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU18=22D24 6t26 61use Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsapl,use Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':neotecter Siecacintion e Test néticial pinadaive snk (rinedfaive/ninedeive) writh e6 usagesprivata aaray edngsylt Accept File g- X Reject File t*a+ 20f2 files →Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.php•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughts>Command docker• docker exec docker lamo 1 pho artisan iiminnv:test-oipedrive-official-sdk 19+7-7+16 -8+32 -8Ask anvthina (*4L)+ &codeSWE-1.62) Reject allAccept all090Nothina to showW Windsurf Teams 191:8 UTF-8 P 4 spaces...
|
49781
|
NULL
|
NULL
|
NULL
|
|
49783
|
1769
|
42
|
2026-05-18T06:58:18.864465+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087498864_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesTools|W FirefoxFileEditViewHistoryBookmarksProfilesTools|WindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:18meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOK DEWNotify the user it adeieted but is used in AJ…..AJREPORTSBacklog[ JY-206763 +000=nouyteuwtwadeleted but is used in AJReportAJRIPORTSBacklogA JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroweeevilsuggestionsAUTO-DETEGTED AGTIVITY TYРОDockoeP JY-204702 •000=8• Mon 18 May 9:58SRD XE3 PronAlte x | EB MC x [ Sche x Cun x | # Cuu x COs: x O Umi x Q MCP X| 0 PipE x Jmi x | C[URL_WITH_CREDENTIALS] YankovLukas Kovalik9:58 AM | Daily - Platform• 11:52|...
|
NULL
|
-4263333930657189208
|
NULL
|
click
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesTools|W FirefoxFileEditViewHistoryBookmarksProfilesTools|WindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:18meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOK DEWNotify the user it adeieted but is used in AJ…..AJREPORTSBacklog[ JY-206763 +000=nouyteuwtwadeleted but is used in AJReportAJRIPORTSBacklogA JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroweeevilsuggestionsAUTO-DETEGTED AGTIVITY TYРОDockoeP JY-204702 •000=8• Mon 18 May 9:58SRD XE3 PronAlte x | EB MC x [ Sche x Cun x | # Cuu x COs: x O Umi x Q MCP X| 0 PipE x Jmi x | C[URL_WITH_CREDENTIALS] YankovLukas Kovalik9:58 AM | Daily - Platform• 11:52|...
|
49780
|
NULL
|
NULL
|
NULL
|
|
49784
|
1770
|
21
|
2026-05-18T06:58:21.046878+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087501046_m2.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFV faVsco.js vVIewINavicareCodeLaravelRefa PhpStormFV faVsco.js vVIewINavicareCodeLaravelRefactorTOOISWindow?° pipedrive-sdk-poc vProject® ActivityController.php© SyncObjects.php• ContractsCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php© createActivityAdded loPlaylistevent.pnp© businessProcess.ong© CreatePlaybookCreatedEvent.php©) salestorce/service.phpcontiguration.pnpc contactkole.ono© UserAutomatedReportsController.phpc) Field.php©FieldData.phpC) FieldValue.php© Layout.phpC)LavoutEntitv.php© Log.php© Profile.php© RecordType.php© SyncBatch.phpElasticSearchc) IntearationApp/Service.php© LeadConverted.php© CreateSelfCoachedEvent.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho© AskAnythingPromptService.php(C)AutomatedReportsCommand.ohvphp api y2.ohd© RequestGenerateReportJob.php© AutomatedReportResult.php© AutomatedReport.php xclass AutomatedReport extends Modelyuenwwwwysrangrrompec/etnowanyerangrrome?46 X1X6^N Feature• OpportunityIM Particinant• PlaybackThemePlaylistI ScorecardN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.phpc Automaleckeport.ono* Get the ID of the automated reportl* dreturn intpublic function getido: int....198199200201202* Get the UUID of the automated report.@return stringpublic function getUvid(): stringf...}(c) AutomatedReportResult.pho© Calendar.phpLocal ChangesShelConsole xLog x + V→ E Side-by-side viewer y= env.local apoA21c62021 envlocallcomooser.ison apolcomooser.lock aodC) Kernel.oho aoo/ConsoleSECURITY_HEADER_CUSTOM_ CSP=php lodaing.oho confialUnversioned Files 10 files=DB_CONNECTION=mysqlDB_HOST=127.0.0.1EDB_PORT=3306=DB_DATABASE=jiminnyEDB_USERNAME=rootDB_PASSWORD=[PASSWORD] DATABASE OHDeTamannyDB PASSWORD OHIOEHelper Code will help IDE to understand your Laravel app code. // Generate // Don't Show Anymore (23 milutec add$0f Daily - Platform • 7m leftU AskJiminnyReportActivityServiceTest~100% 2&• Mon 18 May 9:58:20+0 ..E custom.log#laravel.logA HS_local (jiminny@localhost]console EUA SF [jiminny@localhost]A console (PROD]4 console (STAGING]© TestPipedriveOfficialSdkCommand.php x © Kernel.phpuse Jiminny models redmPipedrive|versions|v1|Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,ACcept Renectuse Pipedrive\versions\v1 \Api \PersonFieldsApi:use Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive\versions\v2\Api\ActivitiesApi;use rrpearive verszons ve Apl AccLvicyrleLasaoLuse Pipedrivelversions\v2\Api\DealFieldsApi;use Pipearive versions vz Ap1 UealSAp1*use Pipearive versions vz Ap1 PersonrielasAp1use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivelversions\v2\Configuration;=1 22Dclass TestPipedrive0fficialSdkCommand extends Command24 đ26 0protected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.onteated sraaintion e roat neiaien Pinatlive so Cotnat ie anatio E6 usagesprivata aray ednesylt y Accept Flle 3- X Reject File o*a+ 2 of 2 files →CascadeO Debugging Pipedrivelest vz APl enapoints with omricial sDKSearched v2 in vendor/pipedrive (2)Analyzed vendor/pipedrive/pipedrive/lib/versions/V2ThoughtsThoughts >Analyzed vendor/pipedrive/pipedrive/lib/versions/V2/Api• TestPipedriveOfficiaSdkCommand.phpTestPipedriveOfficialSdkCommand.phpInouchtsTestPipedriveOfficiaSdkCommand.phpThoughtseammand aocte• docker exec docker lamp 1pho artisan liminnv:test-oipedrive-official-sok 19Ask anything (8AL)+ &CodeSWE-1,6Current versionSECURITY_HEADER_CUSTOM_CSP=DB_CONNECTION=mysqlUb HUsI=marzadbDB_PORT=3306DB_DATABASE=jiminnyDB USERNAMEEnmnyadminDB_PASSWORD=[PASSWORD] \Models\User#CASHIER MODELEJiminny Models Userhubs+7-7+16-8+32-8®Reject allAccept all09048 difterencesWN Windsurf Toams 101-8 UTF.8f?4 spaces...
|
NULL
|
50654230221952769
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFV faVsco.js vVIewINavicareCodeLaravelRefa PhpStormFV faVsco.js vVIewINavicareCodeLaravelRefactorTOOISWindow?° pipedrive-sdk-poc vProject® ActivityController.php© SyncObjects.php• ContractsCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php© createActivityAdded loPlaylistevent.pnp© businessProcess.ong© CreatePlaybookCreatedEvent.php©) salestorce/service.phpcontiguration.pnpc contactkole.ono© UserAutomatedReportsController.phpc) Field.php©FieldData.phpC) FieldValue.php© Layout.phpC)LavoutEntitv.php© Log.php© Profile.php© RecordType.php© SyncBatch.phpElasticSearchc) IntearationApp/Service.php© LeadConverted.php© CreateSelfCoachedEvent.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho© AskAnythingPromptService.php(C)AutomatedReportsCommand.ohvphp api y2.ohd© RequestGenerateReportJob.php© AutomatedReportResult.php© AutomatedReport.php xclass AutomatedReport extends Modelyuenwwwwysrangrrompec/etnowanyerangrrome?46 X1X6^N Feature• OpportunityIM Particinant• PlaybackThemePlaylistI ScorecardN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.phpc Automaleckeport.ono* Get the ID of the automated reportl* dreturn intpublic function getido: int....198199200201202* Get the UUID of the automated report.@return stringpublic function getUvid(): stringf...}(c) AutomatedReportResult.pho© Calendar.phpLocal ChangesShelConsole xLog x + V→ E Side-by-side viewer y= env.local apoA21c62021 envlocallcomooser.ison apolcomooser.lock aodC) Kernel.oho aoo/ConsoleSECURITY_HEADER_CUSTOM_ CSP=php lodaing.oho confialUnversioned Files 10 files=DB_CONNECTION=mysqlDB_HOST=127.0.0.1EDB_PORT=3306=DB_DATABASE=jiminnyEDB_USERNAME=rootDB_PASSWORD=[PASSWORD] DATABASE OHDeTamannyDB PASSWORD OHIOEHelper Code will help IDE to understand your Laravel app code. // Generate // Don't Show Anymore (23 milutec add$0f Daily - Platform • 7m leftU AskJiminnyReportActivityServiceTest~100% 2&• Mon 18 May 9:58:20+0 ..E custom.log#laravel.logA HS_local (jiminny@localhost]console EUA SF [jiminny@localhost]A console (PROD]4 console (STAGING]© TestPipedriveOfficialSdkCommand.php x © Kernel.phpuse Jiminny models redmPipedrive|versions|v1|Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,ACcept Renectuse Pipedrive\versions\v1 \Api \PersonFieldsApi:use Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive\versions\v2\Api\ActivitiesApi;use rrpearive verszons ve Apl AccLvicyrleLasaoLuse Pipedrivelversions\v2\Api\DealFieldsApi;use Pipearive versions vz Ap1 UealSAp1*use Pipearive versions vz Ap1 PersonrielasAp1use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivelversions\v2\Configuration;=1 22Dclass TestPipedrive0fficialSdkCommand extends Command24 đ26 0protected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.onteated sraaintion e roat neiaien Pinatlive so Cotnat ie anatio E6 usagesprivata aray ednesylt y Accept Flle 3- X Reject File o*a+ 2 of 2 files →CascadeO Debugging Pipedrivelest vz APl enapoints with omricial sDKSearched v2 in vendor/pipedrive (2)Analyzed vendor/pipedrive/pipedrive/lib/versions/V2ThoughtsThoughts >Analyzed vendor/pipedrive/pipedrive/lib/versions/V2/Api• TestPipedriveOfficiaSdkCommand.phpTestPipedriveOfficialSdkCommand.phpInouchtsTestPipedriveOfficiaSdkCommand.phpThoughtseammand aocte• docker exec docker lamp 1pho artisan liminnv:test-oipedrive-official-sok 19Ask anything (8AL)+ &CodeSWE-1,6Current versionSECURITY_HEADER_CUSTOM_CSP=DB_CONNECTION=mysqlUb HUsI=marzadbDB_PORT=3306DB_DATABASE=jiminnyDB USERNAMEEnmnyadminDB_PASSWORD=[PASSWORD] \Models\User#CASHIER MODELEJiminny Models Userhubs+7-7+16-8+32-8®Reject allAccept all09048 difterencesWN Windsurf Toams 101-8 UTF.8f?4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49785
|
1769
|
43
|
2026-05-18T06:58:24.383270+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087504383_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFilelEditViewHistoryBookmarksProfilesTools| FirefoxFilelEditViewHistoryBookmarksProfilesTools|WindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:23meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318YSRDXxJm xE3 ProrAtter x | EB MC x [ Sche x ® Cun x | # Cuu x COs: x O Jmi x Q MCP X| 0 PipE x Jmi x| C[URL_WITH_CREDENTIALS] 18 May 9:58L Al BookmarxsNikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 11:58|...
|
NULL
|
-3567506427332769543
|
NULL
|
click
|
ocr
|
NULL
|
FirefoxFilelEditViewHistoryBookmarksProfilesTools| FirefoxFilelEditViewHistoryBookmarksProfilesTools|WindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:23meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318YSRDXxJm xE3 ProrAtter x | EB MC x [ Sche x ® Cun x | # Cuu x COs: x O Jmi x Q MCP X| 0 PipE x Jmi x| C[URL_WITH_CREDENTIALS] 18 May 9:58L Al BookmarxsNikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 11:58|...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49786
|
1770
|
22
|
2026-05-18T06:58:25.929344+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087505929_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormViewINavicareCodeLaravelRefactorTOOISWindo PhpStormViewINavicareCodeLaravelRefactorTOOISWindowFV faVsco.js?° pipedrive-sdk-pocProiect vC ActivityController.ongD Contractsv DCrmc)ConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php© businessProcess.ongcontiguration.pnpcreatePlaybookcreatedevent.ong©) salestorce/service.phpc contactkole.onoc) Field.php© FieldData.phpc) IntearationApp/Service.phpC) LeadConverted.ohgC) CreateSelfCoachedEvent.phpC) FieldValue.php© Layout.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohdC)LavoutEntitv.php@ Loa.ph(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv© Profile.php@ RecordTvpe.ohp(C) AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyosnowanycranyrrompe/? tnowany crangrrom© SyncBatch.phpElasticSearchN Feature* Get the ID of the automated reportlN OpportunitvIM ParticinantM PlavbackTheme* dreturn intD PlaylistD ScorecardN Wehhookpublic function getido: int....© Account.php© Activity.php© Address.phpC) APrompt.pnp* Get the UUID of the automated report.* @return stringc Automaleckeport.ono© AutomatedReportResult.php© Calendar.php(e Colllmnort nhn201202public function getUuid: stringi...Local ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.29> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9:23Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aaol=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU18=22D24 6t26 61use Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsapl,use Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':neotecter Siecacintion e Test néticial pinadaive snk (rinedfaive/ninedeive) writh e6 usagesprivata aaray edngsylt Accept File g- X Reject File t*a+ 20f2 files →Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.php•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughtsCommand docker• docker exec docker lamo 1 pho artisan iiminnv:test-oipedrive-official-sdk 19$0#Daily - Platform • 7 m left100% Sz. Mon 18 May 9:58:25AskJiminnyReportActivityServiceTest v+0 ..w+7-7+16 -8+32 -8Ask anvthina (*4L)+ &codeSWE-1.62) Reject allAccept all090Nothina to showW Windsurf Teams 191:8 UTF-8 P 4 spaces...
|
NULL
|
-1408263943176725407
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormViewINavicareCodeLaravelRefactorTOOISWindo PhpStormViewINavicareCodeLaravelRefactorTOOISWindowFV faVsco.js?° pipedrive-sdk-pocProiect vC ActivityController.ongD Contractsv DCrmc)ConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php© businessProcess.ongcontiguration.pnpcreatePlaybookcreatedevent.ong©) salestorce/service.phpc contactkole.onoc) Field.php© FieldData.phpc) IntearationApp/Service.phpC) LeadConverted.ohgC) CreateSelfCoachedEvent.phpC) FieldValue.php© Layout.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohdC)LavoutEntitv.php@ Loa.ph(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv© Profile.php@ RecordTvpe.ohp(C) AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyosnowanycranyrrompe/? tnowany crangrrom© SyncBatch.phpElasticSearchN Feature* Get the ID of the automated reportlN OpportunitvIM ParticinantM PlavbackTheme* dreturn intD PlaylistD ScorecardN Wehhookpublic function getido: int....© Account.php© Activity.php© Address.phpC) APrompt.pnp* Get the UUID of the automated report.* @return stringc Automaleckeport.ono© AutomatedReportResult.php© Calendar.php(e Colllmnort nhn201202public function getUuid: stringi...Local ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.29> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9:23Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aaol=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU18=22D24 6t26 61use Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsapl,use Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':neotecter Siecacintion e Test néticial pinadaive snk (rinedfaive/ninedeive) writh e6 usagesprivata aaray edngsylt Accept File g- X Reject File t*a+ 20f2 files →Cascade• Debugging Pipedrivelest vz APl enapoints with omricial sDKAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2ThoughtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiThoughts >• TestPipedriveOfficialSdkCommand.php•TestPipedriveOfficialSdkCommand.phpInouchts• TestPipedriveOfficialSdkCommand.phpThoughtsCommand docker• docker exec docker lamo 1 pho artisan iiminnv:test-oipedrive-official-sdk 19$0#Daily - Platform • 7 m left100% Sz. Mon 18 May 9:58:25AskJiminnyReportActivityServiceTest v+0 ..w+7-7+16 -8+32 -8Ask anvthina (*4L)+ &codeSWE-1.62) Reject allAccept all090Nothina to showW Windsurf Teams 191:8 UTF-8 P 4 spaces...
|
49784
|
NULL
|
NULL
|
NULL
|
|
49787
|
1769
|
44
|
2026-05-18T06:58:29.214040+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087509214_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFilelEditViewHistoryBookmarksProfilesToolsW FirefoxFilelEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:28meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOK DEWNotify the user it adeieted but is used in AJ…..AJREPORTSBacklog[ JY-206763 +0a0=deleted but is used in AJReportAJRIPORTSBacklogA JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroweneviileesuggestionsAUTO-DETEGTED AGTIVITY TYРОDeckoeP JY-204702 •00+=SRD XE3 PronAtter x | EB MC x [l Sche x ® Cun x | # Cuu x O Cos: x Jmi x Q MCP X| PipE x | Jmi x | C[URL_WITH_CREDENTIALS] 18 May 9:58L Al BookmarxsNikolay YankovLukas Kovalik9:58 AM | Daily - Platform12:03...
|
NULL
|
-4412174825649830309
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFilelEditViewHistoryBookmarksProfilesToolsW FirefoxFilelEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:28meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOK DEWNotify the user it adeieted but is used in AJ…..AJREPORTSBacklog[ JY-206763 +0a0=deleted but is used in AJReportAJRIPORTSBacklogA JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroweneviileesuggestionsAUTO-DETEGTED AGTIVITY TYРОDeckoeP JY-204702 •00+=SRD XE3 PronAtter x | EB MC x [l Sche x ® Cun x | # Cuu x O Cos: x Jmi x Q MCP X| PipE x | Jmi x | C[URL_WITH_CREDENTIALS] 18 May 9:58L Al BookmarxsNikolay YankovLukas Kovalik9:58 AM | Daily - Platform12:03...
|
49785
|
NULL
|
NULL
|
NULL
|
|
49788
|
1769
|
45
|
2026-05-18T06:58:34.782671+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087514782_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:34meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOKOEWNotify the user it awnoat0omedeieted but is used in AJ…..AJREPORTSBacklog[ JY-206763 +000=nouy thieuetedeleted but is used in AJReportAJRIPORTSBacklogA JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AnerovencvilesuggestionsAUTO-DETEGTED AGTIVITY TYРОDeckoeP JY-204702 •000=F2 ISRD83 3m* PrO404Q0Atter x | EB MC x [l Sche x ® Cun x | * Ciau xO Cost x 0 umi x Q Mcr x 3 Pipe xQSum x• calMon 18 May 9:58nny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613C Projects|* CaucA Serdy XC DevL Al Bockmarxss009 JI-122SS1 1 JT-2001SAllow owner's role to be selected when setting up a trialIn Dev vI Improve Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trial |put the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single selectthis opton shoulont appear wnen eoiting an organisaborAssignee@ Lukas KovalikAssign to meE Galya DimitrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAdd subtaskDevelc omenLinked work itemsAod linked work ibenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnoo d coniernisSuggest a reply.Status update...Thanks...Sub-ProductlAdd optionsGroup: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGDeployedP J-20301 /05(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 1 П •**=Setup test coverage forProphet in SonarЕ3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20091n •*=€Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform12:08...
|
NULL
|
-7583820607986010745
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:34meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOKOEWNotify the user it awnoat0omedeieted but is used in AJ…..AJREPORTSBacklog[ JY-206763 +000=nouy thieuetedeleted but is used in AJReportAJRIPORTSBacklogA JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AnerovencvilesuggestionsAUTO-DETEGTED AGTIVITY TYРОDeckoeP JY-204702 •000=F2 ISRD83 3m* PrO404Q0Atter x | EB MC x [l Sche x ® Cun x | * Ciau xO Cost x 0 umi x Q Mcr x 3 Pipe xQSum x• calMon 18 May 9:58nny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613C Projects|* CaucA Serdy XC DevL Al Bockmarxss009 JI-122SS1 1 JT-2001SAllow owner's role to be selected when setting up a trialIn Dev vI Improve Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trial |put the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single selectthis opton shoulont appear wnen eoiting an organisaborAssignee@ Lukas KovalikAssign to meE Galya DimitrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAdd subtaskDevelc omenLinked work itemsAod linked work ibenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnoo d coniernisSuggest a reply.Status update...Thanks...Sub-ProductlAdd optionsGroup: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGDeployedP J-20301 /05(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 1 П •**=Setup test coverage forProphet in SonarЕ3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20091n •*=€Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform12:08...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49789
|
1769
|
46
|
2026-05-18T06:58:38.947632+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087518947_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:38meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com=Nikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOKOEWNotify the user it adeieted but is used in AJ…..AJREPORTSBacklog[ JY-206763 +as0=deleted but is used in AJReportAJRIPORTSBacklogA JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AnerowenviilesuggestionsAUTO-DETEGTED AGTIVITY TYРОDeckoeP JY-204702 •000=F2 ISRD83 AmiE3 Pron404Q0Q*Atter XxMo xSche x 0 Curs x * Ciau xCost Xom x@va xo Ppt xSum x• calMon 18 May 9:58nny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613C Projects |0084El Datadog O ©* Cau*xIC DevL Al Bockmarxss009 J1-122SS1 1 JT-2001SAllow owner's roje to be selected when setting up a trialIn DevvI Improve Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialo put the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single selectthis opton shoulont appear wnen eoiting an organisaborAssignee@ Lukas KovalikAssign to meE Galya DimitrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAdd subtaskDevelc omenLinked work itemsAod linked work ibenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnood coniernSuggest a reply.Status update...Thanks...Sub-ProductlAdd optionsGroup: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGP J-20301 /05(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 0 П •**=Setup test coverage forProphet in SonarЕ3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20001n •*=€Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 12:12|...
|
NULL
|
-7684361175960393309
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:38meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com=Nikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOKOEWNotify the user it adeieted but is used in AJ…..AJREPORTSBacklog[ JY-206763 +as0=deleted but is used in AJReportAJRIPORTSBacklogA JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AnerowenviilesuggestionsAUTO-DETEGTED AGTIVITY TYРОDeckoeP JY-204702 •000=F2 ISRD83 AmiE3 Pron404Q0Q*Atter XxMo xSche x 0 Curs x * Ciau xCost Xom x@va xo Ppt xSum x• calMon 18 May 9:58nny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613C Projects |0084El Datadog O ©* Cau*xIC DevL Al Bockmarxss009 J1-122SS1 1 JT-2001SAllow owner's roje to be selected when setting up a trialIn DevvI Improve Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialo put the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single selectthis opton shoulont appear wnen eoiting an organisaborAssignee@ Lukas KovalikAssign to meE Galya DimitrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAdd subtaskDevelc omenLinked work itemsAod linked work ibenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnood coniernSuggest a reply.Status update...Thanks...Sub-ProductlAdd optionsGroup: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGP J-20301 /05(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 0 П •**=Setup test coverage forProphet in SonarЕ3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20001n •*=€Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 12:12|...
|
49788
|
NULL
|
NULL
|
NULL
|
|
49790
|
1770
|
23
|
2026-05-18T06:58:40.580624+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087520580_m2.jpg...
|
iTerm2
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormViewINavicareCodeLaravelRefactorTOOISWindo PhpStormViewINavicareCodeLaravelRefactorTOOISWindowFV faVsco.js?° pipedrive-sdk-pocProiectC ActivityController.ongD Contractsv DCrmc)ConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php© businessProcess.ongcontiguration.pnpcreatePlaybookcreatedevent.ong©) salestorce/service.phpcontactkole.onoc) Field.php© FieldData.phpc) IntearationApp/Service.phpC) LeadConverted.ohgC) CreateSelfCoachedEvent.phpC) FieldValue.php© Layout.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohdC)LavoutEntitv.php© Loa.php(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv© Profile.php@ RecordTvpe.ohp(C) AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyosnowanycranyrrompe/? tnowany crangrrom© SyncBatch.phpElasticSearchN Feature* Get the ID of the automated reportlN OpportunitvIM ParticinantM PlavbackTheme* dreturn intD PlaylistD ScorecardN Wehhookpublic function getido: int....© Account.php© Activity.php© Address.phpC) APrompt.pnp* Get the UUID of the automated report.Greturn stringc Automaleckeport.ono© AutomatedReportResult.php© Calendar.php(e Colllmnort nhn201202public function getUuid: stringi...Local ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12:29> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9:23Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aaol==custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmuse Jiminny Models\UserPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsapl,use Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:22Dclass TestPipedrive0fficialSdkCommand extends Command24 6t26 61protected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':neotecter Siecacintion e Test néticial pinadaive snk (rinedfaive/ninedeive) writh e6 usaaesprivata aaray edngsylt Accept File g- X Reject File t*a+ 20f2 files →Nothina to show$0#Daily - Platform • 7 m left100% Sz. Mon 18 May 9:58:40AskJiminnyReportActivityServiceTest v+0 ..Cascade• Debugging PipedriveIpearive (2)ThouahtsAnalyzed vendor/prpedrive/prpedrive/ ulo/verszons/vzinougntsAnalyzed vendor/pzpearzve/pipearive/ ulb/verstons/vz/Ap.unoughts•TestPipedriveOfficialSdkCommand.phpThoughts>• TestPiThouahtsA ToctDi exec docker_lamp_1 php artisan jiminny:test-pipedrive-official-sdk 19-Commandng Pipedrive Official SDK POC for Team ID: 19docker ipedrive account for team: Pipedrive, Inc.Startsi uOAuth tntzatitation: Client initialized successfully in 192.87msroundTest 1eBasac cRuo operations24les 176.28>Ask anvthina (*4L)+ &CodeSWE-1.6+7 -7+16 -8122-02) Reject allAccept all090W Windsurf Teams 191:8 UTF-8 P 4 spaces...
|
NULL
|
5897171199021390585
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormViewINavicareCodeLaravelRefactorTOOISWindo PhpStormViewINavicareCodeLaravelRefactorTOOISWindowFV faVsco.js?° pipedrive-sdk-pocProiectC ActivityController.ongD Contractsv DCrmc)ConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php© businessProcess.ongcontiguration.pnpcreatePlaybookcreatedevent.ong©) salestorce/service.phpcontactkole.onoc) Field.php© FieldData.phpc) IntearationApp/Service.phpC) LeadConverted.ohgC) CreateSelfCoachedEvent.phpC) FieldValue.php© Layout.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohdC)LavoutEntitv.php© Loa.php(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv© Profile.php@ RecordTvpe.ohp(C) AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyosnowanycranyrrompe/? tnowany crangrrom© SyncBatch.phpElasticSearchN Feature* Get the ID of the automated reportlN OpportunitvIM ParticinantM PlavbackTheme* dreturn intD PlaylistD ScorecardN Wehhookpublic function getido: int....© Account.php© Activity.php© Address.phpC) APrompt.pnp* Get the UUID of the automated report.Greturn stringc Automaleckeport.ono© AutomatedReportResult.php© Calendar.php(e Colllmnort nhn201202public function getUuid: stringi...Local ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12:29> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix update to tailed) 1 tile. 17.04.26. 12:56> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9:23Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (22 minutes aaol==custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmuse Jiminny Models\UserPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsapl,use Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:22Dclass TestPipedrive0fficialSdkCommand extends Command24 6t26 61protected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':neotecter Siecacintion e Test néticial pinadaive snk (rinedfaive/ninedeive) writh e6 usaaesprivata aaray edngsylt Accept File g- X Reject File t*a+ 20f2 files →Nothina to show$0#Daily - Platform • 7 m left100% Sz. Mon 18 May 9:58:40AskJiminnyReportActivityServiceTest v+0 ..Cascade• Debugging PipedriveIpearive (2)ThouahtsAnalyzed vendor/prpedrive/prpedrive/ ulo/verszons/vzinougntsAnalyzed vendor/pzpearzve/pipearive/ ulb/verstons/vz/Ap.unoughts•TestPipedriveOfficialSdkCommand.phpThoughts>• TestPiThouahtsA ToctDi exec docker_lamp_1 php artisan jiminny:test-pipedrive-official-sdk 19-Commandng Pipedrive Official SDK POC for Team ID: 19docker ipedrive account for team: Pipedrive, Inc.Startsi uOAuth tntzatitation: Client initialized successfully in 192.87msroundTest 1eBasac cRuo operations24les 176.28>Ask anvthina (*4L)+ &CodeSWE-1.6+7 -7+16 -8122-02) Reject allAccept all090W Windsurf Teams 191:8 UTF-8 P 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49791
|
1769
|
47
|
2026-05-18T06:58:45.735014+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087525735_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:45meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA388latform Team %.Q Search boardKAOTTOK OEWNotify the user it adeieted but is used in A.J..AJREPORTSBacklogP Jy-206763 +000=deleted but is used in AJReportAJRIPORTSBacklogД JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroweneviilesuggestionsAUTO-DETEGTED AGTIVITY TYPODockoeP JY-204702 •00+=F2 (SRD83 3miE3 Pron•Alte x 2 MOP x Sche x © Curs x1 * cia x404Q0• Cost x 0 Jmi x Q Mcr x 3 Pipe xSm xQ• calMon 18 May 9:58nny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613x CauờiC DevL Al Bockmarxs9 J1-122SS1 1 JT-2001SAllow owner's role to be selected when setting up a trialIn DevvI Improve Story~ Details~ DescriptionStoyan il seeing more cases where the Owner doesn't want to connect their calendar and emall to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialput the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single select•this oovon shoulentacoca wnon cottino an oroanisaborAssignee@ Lukas KovalikAssign to meE Galya DimitrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksDevelc omenAooSuoeKLinked work itemsAod linked work ibenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnoo d coniernisSuggest a replyStatus update...Thanks...Sub-ProductlAdd optionsGroup: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGP J-20301 /05(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 1 П ***=Setup test coverage forProphet in SonarЕ3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20001n •*= €Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 12:19...
|
NULL
|
-1034822967256787283
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:45meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA388latform Team %.Q Search boardKAOTTOK OEWNotify the user it adeieted but is used in A.J..AJREPORTSBacklogP Jy-206763 +000=deleted but is used in AJReportAJRIPORTSBacklogД JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroweneviilesuggestionsAUTO-DETEGTED AGTIVITY TYPODockoeP JY-204702 •00+=F2 (SRD83 3miE3 Pron•Alte x 2 MOP x Sche x © Curs x1 * cia x404Q0• Cost x 0 Jmi x Q Mcr x 3 Pipe xSm xQ• calMon 18 May 9:58nny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613x CauờiC DevL Al Bockmarxs9 J1-122SS1 1 JT-2001SAllow owner's role to be selected when setting up a trialIn DevvI Improve Story~ Details~ DescriptionStoyan il seeing more cases where the Owner doesn't want to connect their calendar and emall to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialput the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single select•this oovon shoulentacoca wnon cottino an oroanisaborAssignee@ Lukas KovalikAssign to meE Galya DimitrovaQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksDevelc omenAooSuoeKLinked work itemsAod linked work ibenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnoo d coniernisSuggest a replyStatus update...Thanks...Sub-ProductlAdd optionsGroup: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGP J-20301 /05(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 1 П ***=Setup test coverage forProphet in SonarЕ3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20001n •*= €Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 12:19...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49792
|
1770
|
24
|
2026-05-18T06:58:47.028217+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087527028_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pip ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phcC)LavoutEntitv.php@ Loa.ph© Profile.php@ RecordTvpe.ohp© SyncBatch.phpElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeD PlaylistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibility.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhr@ GenericAiPromnt.nhnC) Groun.nhn@ Inhoy.nho© InboxEmail.php© InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonanyerangrrompeo/.tnonnnycrangrrom.mA6 X1X6^187188189* Get the ID of the automated reportl* @return int191public function getido: ints...?196198* Get the UUID of the automated report.* @return stringpublic function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...;/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated renort* True means active, false means inactivel* Qreturn boolnublde function de+Statuco• hooilHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]22 024 ot2526 6t=2732 6TA console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamtd-':nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive) with exisnrivate arrav Sresults = 1:nnivate EncnuntedTokenManaden CtokenManagen:public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:l$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int SteamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.private function testBasicCrudOperations(SocialAccount $socialAccount): voidX Reject File 0* €Sthis->infod strino: "Test 2• Basic CRUD Onerations')3#Daily - Platform - 7 m left100% 2• Mon 18 May 9:58:46AskJiminnyReportActivityServiceTest vCascade• Debugging PipedriveSearched v2 in vendorloioedrive (2)Analyzed vendor/pzpedrive/pipedriveLib/versions/v2ThouahtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:Thouahts>•TestPipedriveOfficialSdkCommand.phpThoughts• TestPipedriveOfficialSdkCommand.phpThoughts• TestPipedriveOfficialSdkCommand.phpdocker exec docker lamn 1nhn artisan iiminnv.tect-ninedrive-official-cok 10Starting Pipedrive Official SDK POC for Team ID: 19Found Pinedrive account for team: Pinedrive. Inc.Tect 1. MAuth TnitjalizatiorVPASS - DAuth Initialization: Client inttialized successtully in 192.87m.Test 2: Basic CRUD Operations2026-5-18 07.13к2...Token is expired: NOrest zat Get bealsDB token --ErrorCall to undefined method Pipedrivelversions\v2\Api\ DealsApi::getDealsSummarv()at app/Console/Commands/Crm/TestPipedrive0fficialSdkCommand-php: 196+0 ..+7 -7+16 -8+32-8'Retrieved deals In' (selapsed)ms", Selapsed) :catentionse)getferltsurangvoritime) 2000, 2) eole surnary 1n (8e 1aposco)ano", se 1anseo),} catch (Exception $e) 4iveotvectalsda(sdmand.php: 13estGetDea1s(Obtect (Pinedrive|versions|v2\Confiouration))2 files +76-28\Ask anvthina (&4-L)÷ « CodeSWF.16* Reiect allAccent alliWN Windsurf Teamo191-8 LTE.8io 4 spaces...
|
NULL
|
9170100704342485461
|
NULL
|
visual_change
|
ocr
|
NULL
|
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pip ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phcC)LavoutEntitv.php@ Loa.ph© Profile.php@ RecordTvpe.ohp© SyncBatch.phpElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeD PlaylistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibility.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhr@ GenericAiPromnt.nhnC) Groun.nhn@ Inhoy.nho© InboxEmail.php© InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonanyerangrrompeo/.tnonnnycrangrrom.mA6 X1X6^187188189* Get the ID of the automated reportl* @return int191public function getido: ints...?196198* Get the UUID of the automated report.* @return stringpublic function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...;/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated renort* True means active, false means inactivel* Qreturn boolnublde function de+Statuco• hooilHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]22 024 ot2526 6t=2732 6TA console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamtd-':nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive) with exisnrivate arrav Sresults = 1:nnivate EncnuntedTokenManaden CtokenManagen:public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:l$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int SteamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.private function testBasicCrudOperations(SocialAccount $socialAccount): voidX Reject File 0* €Sthis->infod strino: "Test 2• Basic CRUD Onerations')3#Daily - Platform - 7 m left100% 2• Mon 18 May 9:58:46AskJiminnyReportActivityServiceTest vCascade• Debugging PipedriveSearched v2 in vendorloioedrive (2)Analyzed vendor/pzpedrive/pipedriveLib/versions/v2ThouahtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:Thouahts>•TestPipedriveOfficialSdkCommand.phpThoughts• TestPipedriveOfficialSdkCommand.phpThoughts• TestPipedriveOfficialSdkCommand.phpdocker exec docker lamn 1nhn artisan iiminnv.tect-ninedrive-official-cok 10Starting Pipedrive Official SDK POC for Team ID: 19Found Pinedrive account for team: Pinedrive. Inc.Tect 1. MAuth TnitjalizatiorVPASS - DAuth Initialization: Client inttialized successtully in 192.87m.Test 2: Basic CRUD Operations2026-5-18 07.13к2...Token is expired: NOrest zat Get bealsDB token --ErrorCall to undefined method Pipedrivelversions\v2\Api\ DealsApi::getDealsSummarv()at app/Console/Commands/Crm/TestPipedrive0fficialSdkCommand-php: 196+0 ..+7 -7+16 -8+32-8'Retrieved deals In' (selapsed)ms", Selapsed) :catentionse)getferltsurangvoritime) 2000, 2) eole surnary 1n (8e 1aposco)ano", se 1anseo),} catch (Exception $e) 4iveotvectalsda(sdmand.php: 13estGetDea1s(Obtect (Pinedrive|versions|v2\Confiouration))2 files +76-28\Ask anvthina (&4-L)÷ « CodeSWF.16* Reiect allAccent alliWN Windsurf Teamo191-8 LTE.8io 4 spaces...
|
49790
|
NULL
|
NULL
|
NULL
|
|
49793
|
1769
|
48
|
2026-05-18T06:58:48.947648+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087528947_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:48meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOK OEWNotify the user it awnoat0omedeieted but is used in A.J..AJREPORTSBacklog[ JY-206763 +aa0=deleted but is used in AJReportAJRIPORTSBacklogД JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroveacvilesuggestionsAUTO-DETEGTED ACTIVITY TYPGDockoeP JY-204702 •00+=404Q0F2 (SRDE3 Pron*Atte XzMo XSche x © Curs x * Ciau xCost Xoum x@va xo Ppt xSum xQ• cal8• Mon 18 May 9:58nny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613C Projects |El Datadog O ©x CauờiC DevL Al Bockmarxs9 J1-122SS1 1 JT-2001SAllow owner's role to be selected when setting up a trialIn DevvI Improve Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialput the field bellow the Owner emall fieldAssignee@ Lukas KovalikAssign to meE Galya Dimitrova• single selectthis opton shoulont appear wnen eoiting an organisaborQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAdd subtaskLinked work itemsAod linked work ibenDevelc omenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnood coniernSuggest a reply.Status update...Thanks...Sub-ProductlAdd optionsGroup: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGP J-20301 /05(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 1 П ***=Setup test coverage forProphet in Sonar0%00=Е3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20001n •*= €Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 12:22|111...
|
NULL
|
17528887780651265
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform • 7 m left100%8• Mon 18 May 9:58:48meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)AA318Platform Team %.Q Search boardKAOTTOK OEWNotify the user it awnoat0omedeieted but is used in A.J..AJREPORTSBacklog[ JY-206763 +aa0=deleted but is used in AJReportAJRIPORTSBacklogД JY-206151%000Upgrade BE Ibraries - MayMAINTENANCEKacoeE JY-19958AneroveacvilesuggestionsAUTO-DETEGTED ACTIVITY TYPGDockoeP JY-204702 •00+=404Q0F2 (SRDE3 Pron*Atte XzMo XSche x © Curs x * Ciau xCost Xoum x@va xo Ppt xSum xQ• cal8• Mon 18 May 9:58nny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613C Projects |El Datadog O ©x CauờiC DevL Al Bockmarxs9 J1-122SS1 1 JT-2001SAllow owner's role to be selected when setting up a trialIn DevvI Improve Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and email to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialput the field bellow the Owner emall fieldAssignee@ Lukas KovalikAssign to meE Galya Dimitrova• single selectthis opton shoulont appear wnen eoiting an organisaborQuick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAdd subtaskLinked work itemsAod linked work ibenDevelc omenOpen with VS CodeIJ Create branch4 Create commitComponentsPlatformnood coniernSuggest a reply.Status update...Thanks...Sub-ProductlAdd optionsGroup: QueriesAJ Panorama for CallScoring in OD(AUTOMATED AI SCORINGP J-20301 /05(Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 1 П ***=Setup test coverage forProphet in Sonar0%00=Е3 Jy-202720 •.=Sidekick SMS issueDeployedCЕ PY-20001n •*= €Nikolay YankovLukas Kovalik9:58 AM | Daily - Platform• 12:22|111...
|
49791
|
NULL
|
NULL
|
NULL
|
|
49794
|
1769
|
49
|
2026-05-18T06:58:55.711794+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087535711_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 7 m left100% <478• Mon 18 May 9:58:55Nikolay Yankov (Presenting)AAFleTdtM Inbc XBookmarksProfiesTab83 Jm xE3 ProAttc XIxM XSh X 0Cu X *0a x• cos x 0 sm x Q Mc x 3 Po x*0RQ0:0@ Jm x 1 Ock x ^ sio8• Mon 18 May 9:58: https://accounts.google.com/v3/signin/accountchooser?access_type=offline&client_id=1092434469059-baf640tpublohrbvt5kbna.apps.000geusercontent.coma.nouoe.oranteo_scopesstruedreorrect..un%C Projects• Home | Salesforce |DatadogAsely X Ltasansignts & Coachn.D De LUXL Al BockmarxsG Sign in with GoogleChoose an accountto continue tojiminny.comNikolay YankovJiminny neo SAlIintegration Account@ Use another account |detore using tns aop, you can teview pminty coo's Privacy Poagy anol• F)Lukas Kovalik9:58 AM | Daily - Platform...• 12:29...
|
NULL
|
-130246337581483243
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 7 m left100% <478• Mon 18 May 9:58:55Nikolay Yankov (Presenting)AAFleTdtM Inbc XBookmarksProfiesTab83 Jm xE3 ProAttc XIxM XSh X 0Cu X *0a x• cos x 0 sm x Q Mc x 3 Po x*0RQ0:0@ Jm x 1 Ock x ^ sio8• Mon 18 May 9:58: https://accounts.google.com/v3/signin/accountchooser?access_type=offline&client_id=1092434469059-baf640tpublohrbvt5kbna.apps.000geusercontent.coma.nouoe.oranteo_scopesstruedreorrect..un%C Projects• Home | Salesforce |DatadogAsely X Ltasansignts & Coachn.D De LUXL Al BockmarxsG Sign in with GoogleChoose an accountto continue tojiminny.comNikolay YankovJiminny neo SAlIintegration Account@ Use another account |detore using tns aop, you can teview pminty coo's Privacy Poagy anol• F)Lukas Kovalik9:58 AM | Daily - Platform...• 12:29...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49795
|
1769
|
50
|
2026-05-18T06:58:58.748840+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087538748_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindow Help,. 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 7 m left100% C28• Mon 18 May 9:58:58Nikolay Yankov (Presenting)AA3FleTdtM Inbc XBookmarks17 ISR XXJn xX PrOAttc XIа*ОRФ0тОРВа83 MC x (Sch x Cu x | * Cu x 0os x 0 im x QMC x 3 Po x | Jm x | Ca x @ L008• Mon 18 May 9:58ILALOSTINESAGRNESNOK COTCOTNVEOCES UZIOSLAT KOR LEE ЯNOTSANOD УIYEPSARSUI VYLР КERITO GEATLSS ESSSADU TOT 121255R1PL2 JO.A DEXOVRSIFS OUR COVISOCAAAATA- B90UMID AW MIDAV MIDAW MUAM MOAMAAABONN 289B4Y1BWIONN07/5RPWO10SC ProjectsDtn dJcrcrdl a serly XX blass nsgitsa Coachn M Der LUxL Al Bockmarxs|salesforceNikolay Yankov•S*Lukas Kovalik9:58 AM | Daily - Platform• 12:32|Lộ3...
|
NULL
|
3803144119943356364
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindow Help,. 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 7 m left100% C28• Mon 18 May 9:58:58Nikolay Yankov (Presenting)AA3FleTdtM Inbc XBookmarks17 ISR XXJn xX PrOAttc XIа*ОRФ0тОРВа83 MC x (Sch x Cu x | * Cu x 0os x 0 im x QMC x 3 Po x | Jm x | Ca x @ L008• Mon 18 May 9:58ILALOSTINESAGRNESNOK COTCOTNVEOCES UZIOSLAT KOR LEE ЯNOTSANOD УIYEPSARSUI VYLР КERITO GEATLSS ESSSADU TOT 121255R1PL2 JO.A DEXOVRSIFS OUR COVISOCAAAATA- B90UMID AW MIDAV MIDAW MUAM MOAMAAABONN 289B4Y1BWIONN07/5RPWO10SC ProjectsDtn dJcrcrdl a serly XX blass nsgitsa Coachn M Der LUxL Al Bockmarxs|salesforceNikolay Yankov•S*Lukas Kovalik9:58 AM | Daily - Platform• 12:32|Lộ3...
|
49794
|
NULL
|
NULL
|
NULL
|
|
49796
|
1770
|
25
|
2026-05-18T06:58:59.122522+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087539122_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pip ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phcC)LavoutEntitv.php@ Loa.ph© Profile.php@ RecordTvpe.ohp© SyncBatch.phpElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeD PlaylistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibilitv.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhr@ GenericAiPromnt.nhnC) Groun.nhn@ Inhoy.nho© InboxEmail.php© InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonanyerangrrompeo/.tnonnnycrangrrom.mA6 X1X6^187188189* Get the ID of the automated report* @return int191public function getido: ints...?196198* Get the UUID of the automated report.* @return stringpublic function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...;/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated renort* True means active, false means inactivel* Qreturn boolnublde function de+Statuco• hooikHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]22 024 ot2526 6t= 2732 6TA console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AccLvicyrleLasaoLuse Pipedrive\versions\v2\Api\DealFieldsApi:use Pipearive versions vz Ap1 UealsAp1:use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive with exisnrivate arrav Sresults = 1:nnivate EncnuntedTokenManaden CtokenManagen:public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:l$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int $teamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.private function testBasicCrudOperations(SocialAccount $socialAccount): voidX Reject File 0* €Sthis->infod strino: 'Test 2• Basic CRUD Oberations')3#Daily - Platform - 7 m left100% S2• Mon 18 May 9:58:58AskJiminnyReportActivityServiceTest vCascade• Debugging Pipedrive+0 ..Searched v2 in vendorloioedrive (2)Analyzed vendor/pzpedrive/pipedrive/Lib/versions/v2lThouahtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:Thouahts>•TestPipedriveOfficialSdkCommand.php+7 -7Thoughts• TestPipedriveOfficialSdkCommand.php+16 -8Thoughts• TestPipedriveOfficialSdkCommand.php+32-8•docker exec docker lamp 1 php artisan niminny:test-pipedrive-otticial-sdk 19Starting Pipedrive Official SDK POC for Team ID: 19Found Pipedrive account for team: Pipedrive, IncTect 1. OAuth TnitializatioTest 2: Basic CRUDat: 2026-05-48 07:132 ...Token is expired: NOest newieaDB token -ErronCall to undefined method Pipedrive\versions\v2\Api\DealsApi::getDealsSummary()at app/Console/Commands/Crm/TestPipedriveofficialSdkCos carcht texcop.1omstardrine) 20, 2i 4a1 merbrela rolaneenaneftrue) sstaréTine) * 1000, 2); нн о оl пеной. со+ catch (Exception se) (painnyiCons0e/Commanta/CrmtPesEPspedoiveo/tctaCSckCommand:1tes t6etDeals (0bject (Pspedrivelversions|v2/Configuration))aoo/console/Commands/Crm/TestPinedrive0fficialSdkCommand.ohn:84Access to file DealsApi. php is prohibited by •gitignore. You can enable access to gitignore files by enabling the setting Allow Cascade Access to Gitignore Files.Diving2 files +76-28\* Reiect allAccent alliAsk anvthina (&4-L)÷ « CodeSWF.16WN Windsurf Teamo191-8 LTE.8Po 4 spaces...
|
NULL
|
-5916481350149134552
|
NULL
|
click
|
ocr
|
NULL
|
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pip ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phcC)LavoutEntitv.php@ Loa.ph© Profile.php@ RecordTvpe.ohp© SyncBatch.phpElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeD PlaylistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibilitv.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhr@ GenericAiPromnt.nhnC) Groun.nhn@ Inhoy.nho© InboxEmail.php© InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonanyerangrrompeo/.tnonnnycrangrrom.mA6 X1X6^187188189* Get the ID of the automated report* @return int191public function getido: ints...?196198* Get the UUID of the automated report.* @return stringpublic function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...;/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated renort* True means active, false means inactivel* Qreturn boolnublde function de+Statuco• hooikHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]22 024 ot2526 6t= 2732 6TA console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AccLvicyrleLasaoLuse Pipedrive\versions\v2\Api\DealFieldsApi:use Pipearive versions vz Ap1 UealsAp1:use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive with exisnrivate arrav Sresults = 1:nnivate EncnuntedTokenManaden CtokenManagen:public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:l$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int $teamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.private function testBasicCrudOperations(SocialAccount $socialAccount): voidX Reject File 0* €Sthis->infod strino: 'Test 2• Basic CRUD Oberations')3#Daily - Platform - 7 m left100% S2• Mon 18 May 9:58:58AskJiminnyReportActivityServiceTest vCascade• Debugging Pipedrive+0 ..Searched v2 in vendorloioedrive (2)Analyzed vendor/pzpedrive/pipedrive/Lib/versions/v2lThouahtsAnalyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:Thouahts>•TestPipedriveOfficialSdkCommand.php+7 -7Thoughts• TestPipedriveOfficialSdkCommand.php+16 -8Thoughts• TestPipedriveOfficialSdkCommand.php+32-8•docker exec docker lamp 1 php artisan niminny:test-pipedrive-otticial-sdk 19Starting Pipedrive Official SDK POC for Team ID: 19Found Pipedrive account for team: Pipedrive, IncTect 1. OAuth TnitializatioTest 2: Basic CRUDat: 2026-05-48 07:132 ...Token is expired: NOest newieaDB token -ErronCall to undefined method Pipedrive\versions\v2\Api\DealsApi::getDealsSummary()at app/Console/Commands/Crm/TestPipedriveofficialSdkCos carcht texcop.1omstardrine) 20, 2i 4a1 merbrela rolaneenaneftrue) sstaréTine) * 1000, 2); нн о оl пеной. со+ catch (Exception se) (painnyiCons0e/Commanta/CrmtPesEPspedoiveo/tctaCSckCommand:1tes t6etDeals (0bject (Pspedrivelversions|v2/Configuration))aoo/console/Commands/Crm/TestPinedrive0fficialSdkCommand.ohn:84Access to file DealsApi. php is prohibited by •gitignore. You can enable access to gitignore files by enabling the setting Allow Cascade Access to Gitignore Files.Diving2 files +76-28\* Reiect allAccent alliAsk anvthina (&4-L)÷ « CodeSWF.16WN Windsurf Teamo191-8 LTE.8Po 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49797
|
1769
|
51
|
2026-05-18T06:59:01.795597+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087541795_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform - 6 m left100%8• Mon 18 May 9:59:01meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com=Nikolay Yankov (Presenting)AA3FleTátTabXJn xX PrO8• Mon 18 May 9:50C ProjectsAttc XI83 мс X• Home | SalesforceCurE Datadog0Sm xQ мс|salesforceTane oe n, cheset ypou saemasne ned pannseword. W you stilSalesforce loginOd UsernamnMkoley vonkofemintcon•$E*C Dev@ uxAune 3-4, 2026 | ChicagoBold marketers. Breakthroughagents. Big impact.Al is reshaping marketing. Learn what's driving revenue right now. Build yourAgentic Enterprise. Only at Connections.Register now C?Nikolay YankovLog In to Sandbox• Kemember meForpot. Your Password?Cusom DomainCNXO 2026 Salesforce, Inc. All rights reserved. I PivacyLukas Kovalik9:59 AM | Daily - PlatformLộ3• 12:35|...
|
NULL
|
-9059278532528567015
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform - 6 m left100%8• Mon 18 May 9:59:01meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com=Nikolay Yankov (Presenting)AA3FleTátTabXJn xX PrO8• Mon 18 May 9:50C ProjectsAttc XI83 мс X• Home | SalesforceCurE Datadog0Sm xQ мс|salesforceTane oe n, cheset ypou saemasne ned pannseword. W you stilSalesforce loginOd UsernamnMkoley vonkofemintcon•$E*C Dev@ uxAune 3-4, 2026 | ChicagoBold marketers. Breakthroughagents. Big impact.Al is reshaping marketing. Learn what's driving revenue right now. Build yourAgentic Enterprise. Only at Connections.Register now C?Nikolay YankovLog In to Sandbox• Kemember meForpot. Your Password?Cusom DomainCNXO 2026 Salesforce, Inc. All rights reserved. I PivacyLukas Kovalik9:59 AM | Daily - PlatformLộ3• 12:35|...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49798
|
1769
|
52
|
2026-05-18T06:59:06.397337+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087546397_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
|
[{"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}]...
|
8043719072324535154
|
-8628527368849355612
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
FirefoxFileEditViewHistor Project: faVsco.js, menu
FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform - 6 m leftmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com100%8• Mon 18 May 9:59:05=Nikolay Yankov (Presenting)3FleTátM Inbc XTab83 Jm8• Mon 18 May 9:50C7 ISRC ProjectsX PrOAttc XI83 мC XCQ Sch xo Cu X* Ca xCos X0m x Q мc x3 Po X© Jmx0c x•MOANVDANWDAWAAABUAN2000- 00 я— DevsalesforceSalesforce loginMieoley vankowutenirconJune 3-4, 2026 | ChicagoBold marketers. Breakthroughagents. Big impact.Al is reshaping marketing. Learn what's driving revenue right now. Build yourAgentic Enterprise. Only at Connections.Register now C?Nikolay Yankov•$Password2 Remember meForgot Your Password?Log In to Sa à box• F)CNX© 2026 Salesforce, Inc. All righes reverved.Lukas Kovalik9:59 AM | Daily - Platform• 12:40Lộ3...
|
49797
|
NULL
|
NULL
|
NULL
|
|
49799
|
1770
|
26
|
2026-05-18T06:59:07.974613+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087547974_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pip ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phcC)LavoutEntitv.php@ Loa.phc) Pronlle.ono@ RecordTvpe.ohpC) SvncBatch.ohvElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeM PlavlistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibility.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhnl@ GenericAiPromnt.nhnC) Groun.nhn© Inbox.php© InboxEmail.php©InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© SaveActivity.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonawyerangfrompeo/.tnonnnyerangrrom.uA6 X1X6^187188* Get the ID of the automated reportl* dreturn intpublic function getido: ints...?* Get the UUID of the automated report.* Greturn strina201202public function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...}/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated report* True means active., false means inactivel* Qreturn boolnublde function de+Statuco• hooilHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.loglaravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]22024 ot26 6t32 61A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipearive versions vz Ap1 Personr1elasAp1*use Pipearive versions vz Ap1 PersonsAp1use Pipedrive verszons vz contzquratzon:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive with exisnrivate arrav Sresults = 1:nnivate EncnuntedTokenManaden CtokenManagen:public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:l$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int SteamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.private function testBasicCrudOperations(SocialAccount $socialAccount): voidX Reject File 0* €Sthis->infod strino: 'Test 2• Basic CRUD Oberations')3"Dally - Platrorm• om lert100% S2. Mon 18 May 9:59:07U AskJiminn• Debugging Pipedrive+0 ..current workspaceG00c Review PR for Activity StageManual Testing HubSpot Paginationc, Activity Stage Discrepancy Analysis•TestPipedriveOfficialSdkCommand.php+16 -8Inoughts• TestPipedriveOfficialSdkCommand.php+32 -8•docker exec docker lamp 1 pho artisan liminnv:test-oipedrive-official-sdk 19Starting Pipedrive Official SDK POC for Team ID: 19round Pipedrive account for team: Pipedrive, IncTest 1. SAuth Uth tialtzatiation: Client initialized successfully in 192,87mses token Tene thuo oeerationsToken is expired: Nd202-05-18 67: y...Test 2a: Get DeaSB token -ErrorCall toundefined method Pinedrivelvercionciw2lAnilNealcint:.netnealcCummarvlyapp/ Console/Commands/Crm/TestP1pedrive0fficialsdkcome truenand,ptarttarcordResult("'Get Deals', true, "Retrieved deals 2n'(selapsed)mgi selancea).deale cummarv in Seelancedimcl, Celanced).nallienisAccess to flle DealsAni,nho is prohibited by,nitianore. You can enable access to citicnore filles by enablina the setting Alllow Cascade Access to Gitinnore BilesAccess to directory Api is prohibited by •gitignore. You can enable access to gitignore files by enabling the setting Allow Cascade Access to Gitignore Files2 files +76-28\* Reiect allAccent alliAsk anvthina (&4-L)÷ « CodeSWF.16WN Windsurf Teams200-22-io 4 spaces...
|
NULL
|
3067404727576630445
|
NULL
|
visual_change
|
ocr
|
NULL
|
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pip ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phcC)LavoutEntitv.php@ Loa.phc) Pronlle.ono@ RecordTvpe.ohpC) SvncBatch.ohvElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeM PlavlistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibility.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhnl@ GenericAiPromnt.nhnC) Groun.nhn© Inbox.php© InboxEmail.php©InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© SaveActivity.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonawyerangfrompeo/.tnonnnyerangrrom.uA6 X1X6^187188* Get the ID of the automated reportl* dreturn intpublic function getido: ints...?* Get the UUID of the automated report.* Greturn strina201202public function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...}/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated report* True means active., false means inactivel* Qreturn boolnublde function de+Statuco• hooilHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.loglaravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]22024 ot26 6t32 61A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipearive versions vz Ap1 Personr1elasAp1*use Pipearive versions vz Ap1 PersonsAp1use Pipedrive verszons vz contzquratzon:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive with exisnrivate arrav Sresults = 1:nnivate EncnuntedTokenManaden CtokenManagen:public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:l$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int SteamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.private function testBasicCrudOperations(SocialAccount $socialAccount): voidX Reject File 0* €Sthis->infod strino: 'Test 2• Basic CRUD Oberations')3"Dally - Platrorm• om lert100% S2. Mon 18 May 9:59:07U AskJiminn• Debugging Pipedrive+0 ..current workspaceG00c Review PR for Activity StageManual Testing HubSpot Paginationc, Activity Stage Discrepancy Analysis•TestPipedriveOfficialSdkCommand.php+16 -8Inoughts• TestPipedriveOfficialSdkCommand.php+32 -8•docker exec docker lamp 1 pho artisan liminnv:test-oipedrive-official-sdk 19Starting Pipedrive Official SDK POC for Team ID: 19round Pipedrive account for team: Pipedrive, IncTest 1. SAuth Uth tialtzatiation: Client initialized successfully in 192,87mses token Tene thuo oeerationsToken is expired: Nd202-05-18 67: y...Test 2a: Get DeaSB token -ErrorCall toundefined method Pinedrivelvercionciw2lAnilNealcint:.netnealcCummarvlyapp/ Console/Commands/Crm/TestP1pedrive0fficialsdkcome truenand,ptarttarcordResult("'Get Deals', true, "Retrieved deals 2n'(selapsed)mgi selancea).deale cummarv in Seelancedimcl, Celanced).nallienisAccess to flle DealsAni,nho is prohibited by,nitianore. You can enable access to citicnore filles by enablina the setting Alllow Cascade Access to Gitinnore BilesAccess to directory Api is prohibited by •gitignore. You can enable access to gitignore files by enabling the setting Allow Cascade Access to Gitignore Files2 files +76-28\* Reiect allAccent alliAsk anvthina (&4-L)÷ « CodeSWF.16WN Windsurf Teams200-22-io 4 spaces...
|
49796
|
NULL
|
NULL
|
NULL
|
|
49800
|
1769
|
53
|
2026-05-18T06:59:09.381442+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087549381_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfiles|→Tools FirefoxFileEditViewHistoryBookmarksProfiles|→ToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 6 m left100% <78• Mon 18 May 9:59:08=Nikolay Yankov (Presenting)AA3FleTdtM Inb XT0Q0:052 (sRxXJm xX PrOIAttc XI8MC x (sch x O Cu x | * Cu x os x 0 im x Q MC x | 9 Pp x ||Suexoa xhttps://fiminny--stagingenv.sandbox.my.salesforce.com/_u/system/security/ChangePassword?retURL=%2Fsetup%2Fsecur%2FRAcoess Authorizatonvage.apexpnsesourot ASocAAAAL-_BYJUMDAWMDAWMDA ЯL JeinyC ProjectsUDataos93A sely X Mtasnsignts & Coachn.De LUX8• Mon 18 May 9:508 ChL Al BockmarxsNikolay Yankov•$Lukas Kovalik9:59 AM ||Daily - Platform12:43Lộ3...
|
NULL
|
1448308521804049096
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfiles|→Tools FirefoxFileEditViewHistoryBookmarksProfiles|→ToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform - 6 m left100% <78• Mon 18 May 9:59:08=Nikolay Yankov (Presenting)AA3FleTdtM Inb XT0Q0:052 (sRxXJm xX PrOIAttc XI8MC x (sch x O Cu x | * Cu x os x 0 im x Q MC x | 9 Pp x ||Suexoa xhttps://fiminny--stagingenv.sandbox.my.salesforce.com/_u/system/security/ChangePassword?retURL=%2Fsetup%2Fsecur%2FRAcoess Authorizatonvage.apexpnsesourot ASocAAAAL-_BYJUMDAWMDAWMDA ЯL JeinyC ProjectsUDataos93A sely X Mtasnsignts & Coachn.De LUX8• Mon 18 May 9:508 ChL Al BockmarxsNikolay Yankov•$Lukas Kovalik9:59 AM ||Daily - Platform12:43Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49801
|
1769
|
54
|
2026-05-18T06:59:14.509955+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087554509_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
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% (478• Mon 18 May 9:59:14AA3FleTátM Inbc XBookmarksF7 (SR XProfies83 Jm xE3 Prohttps://app.jiminny.comL JeinyProjects2n leawsAttcX8MC x (Sch x Cu x | *Cu x Co x 0im x Q MC x0.QФ:03 Po X0Jm x |0c x Cch8• Mon 18 May 9:50E3 SSHeсrокс@ Sentry *X CJ Tasksinsights & Coachin— DevL UXsalesforceChange [PASSWORD_FIELD] a new password for [EMAIL] sure to include at leastO 8charactersO 1 letterO 1 number*New PasswordNikolay Yankov*Conam herwoesswordVanswvord was last Changed on 2/2/2040 5:857141© 2026 Salesforce, Inc. All rights reservedLukas Kovalik9:59 AM ||Daily - PlatformLộ3..•• 12:48|...
|
NULL
|
5483582165953491269
|
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% (478• Mon 18 May 9:59:14AA3FleTátM Inbc XBookmarksF7 (SR XProfies83 Jm xE3 Prohttps://app.jiminny.comL JeinyProjects2n leawsAttcX8MC x (Sch x Cu x | *Cu x Co x 0im x Q MC x0.QФ:03 Po X0Jm x |0c x Cch8• Mon 18 May 9:50E3 SSHeсrокс@ Sentry *X CJ Tasksinsights & Coachin— DevL UXsalesforceChange [PASSWORD_FIELD] a new password for [EMAIL] sure to include at leastO 8charactersO 1 letterO 1 number*New PasswordNikolay Yankov*Conam herwoesswordVanswvord was last Changed on 2/2/2040 5:857141© 2026 Salesforce, Inc. All rights reservedLukas Kovalik9:59 AM ||Daily - PlatformLộ3..•• 12:48|...
|
49800
|
NULL
|
NULL
|
NULL
|
|
49802
|
1769
|
55
|
2026-05-18T06:59:17.496463+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087557496_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
7558552253815835299
|
-8132289082607555642
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% C78• Mon 18 May 9:59:17Nikolay Yankov (Presenting)AAYSRXXJm xE3 Pro•Atte XI83 MC x [ Sch x0 Cu X *Ca xCos XoJm x@Mo x*ORGO:03 Po X© JmX0c xhttps://aco.jiminny.com/dashboardC Projectsel ANSE3 SSH• Home | Salesforce* ClaudeSentry0 TusksMy RecordingsTeam RecordingsEveryone's RecordingsTrending this monthLive FeedNikolay Yankov at Jiminny (EU)®#12 Feb, 10:19 AMNikolay Yankov at Jiminny (EU)®#Miguel Hernandez at Cayetano *Mectwith Reckxfrom EminoxD 4ScheduleInvite NotetakerUntnowncurtomerNotetaker added by Nikolay YankovThis WeekTeam Schedule• DevNo Activity8• Mon 18 May 9:50Nikolay YankovNotetaker added by Nikolay YankovUnknown CustomerNotetaker added by Nikolay Yankov18Notetaker added by Nikolay YankovNotetaker added by Nikolay Yankov21 Jan, 1.02 PMUrwnowmcuromer31 Mar. 2025,4-43 PMNo MoetingsLukas Kovalik9:59 AM | Daily - Platform• 12:51|...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49803
|
1769
|
56
|
2026-05-18T06:59:20.547071+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087560547_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
7266624862028544203
|
577591577001045378
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform - 6 m left100% C8• Mon 18 May 9:59:20meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com=Nikolay Yankov (Presenting)EditAA• •(1883 Jm xE3 ProAite X83 мC XCa Schx*09G0*© cu x | * cu x 0 cos x | 0 Jm x Q MC x | 3 Pp x 1Smx0d x8• Mon 18 May 9:50https://aco.jiminny.com/klosk,L JeonyProjects2n leAsE3 SSH• Home | Salesforcee Crcke!• Sentry *X C Tusksa Insights & CoachinC DevMy RecordingsTeam RecordingsEveryone's RecordingsLive FeedNikolay Yankov at Jimincy (EU)®#12 Feb, 10:19 AMNikolay Yankov at Jiminny (EU)Ф#UwnownourtomerNotetaker added by Nikolay Yankov3OJan--7PMNotetaker added by Nikolay YankovUnicnown CustomerNotetaker added by Nikolay YankovUetneweunometNotetaker added by Nikolay YankovSettingsKioskalker added by Nikolay Yankov{03 Organization2 ProfileLogoutncuttomerr.2025,443 PMTrending this monthOliver Harris listened to call 60Miguel Hernandez at Cayetano *fMoctwith Reckefrom liminexD 4Held: 19 Dec. 2025, 12:28 PMÔ Duration: 28m d Value: C6.664Oliver Harris listened to call 6d15 May. 4.43 PMScheduleUhiueNotKoncThis WeckTeam Schedule# Held: 14 May.4.31PMÔ Duration 17m& Value: U$$9,900Stoyan Tanev listened to call 6d15 May, 141PMSupport /Troubleshooting with Jessica ThomasHeld: 12May. 11:28 AMÔ Duration: 27m&Value: €128.298Stoyan Tanev listened to call 6d15 May. 1:39 PMDiscovery with Derek FreybergHeld: 13 May. 6:00 PMÔ Duration: 29-& Value: US$2.700No MoetingsStoyan Taney Istened to call 6aDiscovery Call (upsell) with Frankle Bryant15 May. 1:32 PM|G Held: 14 May, 258 PMÔ Duration: 12m&, Value: US$20.349Adelina Petrova istened to call 6a15 May. 11:11AMtwwwUnknowncuscommerNikolay YankovLukas KovalikLộ39:59 AM | Daily - Platform12:54...
|
49802
|
NULL
|
NULL
|
NULL
|
|
49805
|
1770
|
27
|
2026-05-18T06:59:22.706272+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087562706_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, 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},{"role":"AXButton","text":"pipedrive-sdk-poc, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.05618351,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
3036442092684777152
|
-5740307667640416884
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
V Project: faVsco.js, menu
pipedrive-sdk-poc, menu
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phrC)LavoutEntitv.php@ Loa.phc) Pronlle.ono@ RecordTvpe.ohpC) SvncBatch.ohvElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeM PlavlistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibilitv.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhnl@ GenericAiPromnt.nhnC) Groun.nhn© Inbox.php© InboxEmail.php©InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© SaveActivity.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonawyerangrrompeo/.tnonnnycrangrrom.wA6 X1X6^187188* Get the ID of the automated reportl* dreturn intpublic function getido: ints...?* Get the UUID of the automated report.* Greturn strina201202public function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...}/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated report* True means active., false means inactivel* Qreturn boolnublde function de+Statuco• hooilHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU22 024 ot26 6t32 6Tuse Jiminny models redmACcept RenectuseActivityFieldsApi;use Pipedrive verszons ivelapt beatrtecasaptyuse Pipedrive verstons velapt beatsaptyuse Pipedrive\versions\v1 \Api\PersonFieldsApi;use Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions vz Ap1 Personr1elasAp1*use Pipearive versions vz Ap1 PersonsAp1*use Pipedrive verszons vz contzquratzon:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamtd-':nrotected Sdescrintion = 'Test official Pinedrive Sik (ninedrive/ninedrive) with exisnrivate arrav Sresults = 1:nnivate EncnuntedTokenManaden CtokenManagen:public function_construct(EncryptedTokenManager $tokenManager)parent:: constructO:l$this->tokenManager = $tokenManager:public function handled: intf...}1 usageprivate function runTests(int $teamId): void{...}private function testOAuthInitialization(SocialAccount SsocialAccount): void{...}1usade.private function testBasicCrudOperations(SocialAccount SsocialAccount): voidX Reject File 0* €Sthis->infod strino: "Test 2• Basic CRUD Oberations')3"Dally - Platrorm• om lert100% S2• Mon 18 May 9:59:22U AskJiminnDebugging Pipedrive S+0 ..© Dashboard Activity Debugging© Trial Owner Role Selection00© Event Serialization Requirement The user wants to determine if the SerializesModels trait is necessary in the AutomatedReportGenerated event class to support the TrackAutomatedRepo... 6dC Fixina Automated Report Job Failure Due to Missina PoF URIсолел тея ви Хоу озлн судку...Token is expired: NOrest zst Get bealsDB token --ErrorCall to undefined method Pipedrive\versions\v2\Api\DealsApi::getDealsSummary()a onarteve deat, I' (se lopsed)es", se apsced) :(Exception se)sstarétine), « 1000, 2) decals sunnary in (&e lapsed)ma, se lapsed).Access. to_file. DealsAni.nho.is.orohibited.by.aitianore. You.can enable. access.to_citionore.files.by.enablino.the.settino.A11owGascade Accessto Gitinnore BilesThouahts >Access to directory Ap1 is prohibited by .qitignore. You can enable access to gitignore tiles by enabling the setting ALlow cascade Access to Git1qInoughtsI'm using the official SDK v2 now (updated from v1), but the v2 SDK has different method names than v1. The method getDealsSummary( ) doesn't exist in v2, and I can't access theCurrent status•Using: Pipedrive\versions\v2 (updated from v1)• Issue: Method names difter between vi and v2• Cannot insnect v2 SDK source code to find correct method namec1 Ieam Cok tukink wa knaw worke - 0/10 tocte naccody2. You provide the correct v2 method names from Pioedrive documentationi3. I try common method names in v2 (getDeals, listDeals, etc.)4. Use direct HtTP calls for v2 APl endpointsWhich annroach would vou nrefer?Tenli axe2 files +76-28\* Reiect alliiAccent alliAsk anvthina (&4-L)÷ « CodeSWF.16WN Windsurf Teams200-221UTE.8Po 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49804
|
1769
|
57
|
2026-05-18T06:59:22.706286+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087562706_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
|
[{"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}]...
|
8043719072324535154
|
-8628527368849355612
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
FirefoxFileEditView→Nikol Project: faVsco.js, menu
FirefoxFileEditView→Nikolay Yankov (Presenting)HistoryBookmarksProfilesToolsWindowHelp> 0.Daily - Platform • 6 m leftmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com100% <478• Mon 18 May 9:59:22AA+CrouusTátDOOBIETKTab83 Jm xE3 ProAttcXIE3MC x (Sch x O Cu x | * Ca x |0os x | 0 sm x Q MC x 3 Pp x0.00:0ta QSae xoa xoл8• Mon 18 May 9:59https://apo.jiminny.com/kiosk- JenC Projects2 SSHHome | SalestorceJ crckela seky yxL tasks© DevAwaarareKioskOrganizationsSetup AccountNAME +OWNER +Aulomarco KeoorhMobile versionNikolay Yankov•$Lukas Kovalik9:59 AM ||Daily - Platform• 12:56|Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49807
|
1770
|
28
|
2026-05-18T06:59:28.000557+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087568000_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pip ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phcC)LavoutEntitv.php© Loa.phpc) Pronlle.ono@ RecordTvpe.ohpC) SvncBatch.ohvElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeM PlavlistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibilitv.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhnl@ GenericAiPromnt.nhnC) Groun.nhn© Inbox.php© InboxEmail.php©InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© SaveActivity.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonawyerangrrompeo/.tnonnnycrangrrom.wA6 X1X6^187188* Get the ID of the automated reportl* dreturn intpublic function getido: ints...?* Get the UUID of the automated report.* Greturn strina201202public function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...}/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated report* True means active., false means inactivel* Qreturn boolnublde function de+Statuco• hooilHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmuse Pipedrive verszons vz Ap1 ACCIviclesAp1use Pipedrive\versions\v2\Api ActivityFieldsApi:use Pipedrave verszons vz Ap1 Ueaurielasap1use Pipedrive\versions\v2 \Api\DealsApi:use Pipedrive\versions(v2\Api\PersonFieldsApi:use Pipedrive verszons vc Ap1 PersonsAD1.use Pipedrive versions vz contzquration.11 usage22024026 O1132 6Tprotected Ssignature = "11minnv:test-p1pedrive-officral-sok teamid-'*protected Sdescrintion = ITest official Pinednive SDK (oinedrive/pinednive) with exiorivate arrav Sresults = 13lusageprivate EncryptedTokenManager $tokenManager:no usagespublic function __construct(EncryptedTokenManager $tokenManager)parent:: construct?).sthls->cokennanager = scokenmanager;public function handled: intf...}private function runTests(int SteamId): void{...}1 usageprivate function testOAuthInitialization(SocialAccount SsocialAccount): voidf...?11 usageorivate function testBasicCrudOperations(SocialAccount SsocialAccount: void$this->info( string: 'Test 2: Basic CRUD Operations'):tny-Il Get the naw token from datahaseSnawhhToken = ScocialAccount->ae+ProviderilsenToken0•.strlen(SrawDbToken)."")•Trial Owner Role SelecNot Shown when editingModal used for botn create/editOwner gets selected role + AdminAlways gets Admin + RecorderKeplace Uppontuniy sync Perlod locatlolCurrently at lines 71-84Part of Create TeamHandled in SditTeamModalImplementation PlanFrontend Changes1. EditTeamModal.vue• Add role selection tield below Owner email (after line 39Onlv show when creatina team ( Iflaas.teamGreated )•Move Opportunity Sync Period field to 3rd row, 1st column (after CRM field)Add role options: Recorder, Recorder & Voice, Analyst• Add owner role to form state1. CreateTeamRequest.oho• Add validation rule for ouner role field• Allowed values: recorder, recorder and voice, analyst• Onlv required when creatina (not editina)2. UserinvitationDTO::forOwner()• Accept owner_role parameter from request• Map role name to role IDAlways add ROLE_ADMIN to the role IDs (as per requirement: "selected role + Admin permissions")• Replace hardcoded ROLE RECORDER with selected role3. EditTeamRequest.php• Ensure ouner role is NOT acceoted when editina (validation should reiect it)Key Files to Modify1. /front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue2. /app/Http/Requests/Settings/Teams/CreateTeamRequest.php3./app/DT0/Inv1tation/UserInv1tat1onDT0.php4./app/Htto/Requests/Settinas/Teams/EdiitTeamRequest.ohoTectina Considerationc•Test role assignment for all 3 options (Recorder, Recorder & Voice, Analyst)Verity Admin permission is alwavs addedEnsure field is hidden when editing existing team• Verify Opportunity Sync Period moves to correct location• Test owner sign-in flow with each role option"Dally - Platrorm• om lert100% 2. Mon 18 May 9:59:27AskJiminnyReportActivityServiceTest v+0 ..Condition: v-ir="!Tlags. teamcreated"Modify UserInvitationDT0:: for0wner() to use selected role + AdminMove Opportunity Sync Period, add role field in its placesame component handles bothwCal aAsk anvthina &4DSWF.16WN Windsurf Teams200-22 UTF.8Po 4 spaces...
|
NULL
|
-321692654254877741
|
NULL
|
click
|
ocr
|
NULL
|
ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pip ViewLaravelRefactorGitWindowHelpFV faVsco.js?° pipedrive-sdk-poc vD Contracts• Cm© businessProcess.ong© ContactRole.php© Field.php© FieldData.php© FieldValue.php© Layout.phcC)LavoutEntitv.php© Loa.phpc) Pronlle.ono@ RecordTvpe.ohpC) SvncBatch.ohvElasticSearchM FeatureN OpportunitvIM ParticinantM PlavbackThemeM PlavlistN ScorecardlN Wehhook© Account.php© Activity.php© Address.php© AiPrompt.php© AutomatedReport.php© AutomatedReportResult.php© Calendar.php© Callimport.php© CoachingFeedback.php© CoachingFeedbackVisibilitv.php@ CoachinaSection.ohp© CoachinaSectionCriterion.php© CoachinaSectionCriterionFeedback.pho© CoachinaSectionFeedback.phpC CommentAbstract.oho@ Commentinterface.ohv(C) Contact.oho@ Device.nhoC) EmailMeccage.nhnl@ GenericAiPromnt.nhnC) Groun.nhn© Inbox.php© InboxEmail.php©InboxEmailBatch.php© Invitation.php@ JobLog.php© JobTitle.php© Lanquage.php© LanquageDialect.php@ ActivitvController.hr© ConvertLeadActivities.php© SaveActivity.php© PurgeLookupCache.php© SyncPlanhat.php© CreatePlaybookCreatedEvent.phpAcuivityLeadConverted.php© Salesforce/Service.php© UserAutomatedReportsController.php© IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.php© CreateCommentedEvent.phpC) CreateSmsSentEvent.phg© PlanhatActivityListener.php©[EMAIL]©AutomatedReportsCommand.ohpphp api y2.ohdC) RequestGenerateReport.Job.ohv© AutomatedReportResult.php(C) AutomatedRenort nhn Xclass AutomatedReport extends Modelyuenonawyerangrrompeo/.tnonnnycrangrrom.wA6 X1X6^187188* Get the ID of the automated reportl* dreturn intpublic function getido: ints...?* Get the UUID of the automated report.* Greturn strina201202public function getUuid(): stringf...}* Get the team ID of the automated report.* @neturn intpublic function getTeamIdO: intf...}/*** Get the tupe of the automated report.* dreturn stringpublic function getType@: stringf...}* Get the status of the automated report* True means active., false means inactivel* Qreturn boolnublde function de+Statuco• hooilHelner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (24 minutes adol=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmuse Pipedrive verszons vz Ap1 ACCIviclesAp1use Pipedrive\versions\v2\Api ActivityFieldsApi:use Pipedrave verszons vz Ap1 Ueaurielasap1use Pipedrive\versions\v2 \Api\DealsApi:use Pipedrive\versions(v2\Api\PersonFieldsApi:use Pipedrive verszons vc Ap1 PersonsAD1.use Pipedrive versions vz contzquration.11 usage22024026 O1132 6Tprotected Ssignature = "11minnv:test-p1pedrive-officral-sok teamid-'*protected Sdescrintion = ITest official Pinednive SDK (oinedrive/pinednive) with exiorivate arrav Sresults = 13lusageprivate EncryptedTokenManager $tokenManager:no usagespublic function __construct(EncryptedTokenManager $tokenManager)parent:: construct?).sthls->cokennanager = scokenmanager;public function handled: intf...}private function runTests(int SteamId): void{...}1 usageprivate function testOAuthInitialization(SocialAccount SsocialAccount): voidf...?11 usageorivate function testBasicCrudOperations(SocialAccount SsocialAccount: void$this->info( string: 'Test 2: Basic CRUD Operations'):tny-Il Get the naw token from datahaseSnawhhToken = ScocialAccount->ae+ProviderilsenToken0•.strlen(SrawDbToken)."")•Trial Owner Role SelecNot Shown when editingModal used for botn create/editOwner gets selected role + AdminAlways gets Admin + RecorderKeplace Uppontuniy sync Perlod locatlolCurrently at lines 71-84Part of Create TeamHandled in SditTeamModalImplementation PlanFrontend Changes1. EditTeamModal.vue• Add role selection tield below Owner email (after line 39Onlv show when creatina team ( Iflaas.teamGreated )•Move Opportunity Sync Period field to 3rd row, 1st column (after CRM field)Add role options: Recorder, Recorder & Voice, Analyst• Add owner role to form state1. CreateTeamRequest.oho• Add validation rule for ouner role field• Allowed values: recorder, recorder and voice, analyst• Onlv required when creatina (not editina)2. UserinvitationDTO::forOwner()• Accept owner_role parameter from request• Map role name to role IDAlways add ROLE_ADMIN to the role IDs (as per requirement: "selected role + Admin permissions")• Replace hardcoded ROLE RECORDER with selected role3. EditTeamRequest.php• Ensure ouner role is NOT acceoted when editina (validation should reiect it)Key Files to Modify1. /front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue2. /app/Http/Requests/Settings/Teams/CreateTeamRequest.php3./app/DT0/Inv1tation/UserInv1tat1onDT0.php4./app/Htto/Requests/Settinas/Teams/EdiitTeamRequest.ohoTectina Considerationc•Test role assignment for all 3 options (Recorder, Recorder & Voice, Analyst)Verity Admin permission is alwavs addedEnsure field is hidden when editing existing team• Verify Opportunity Sync Period moves to correct location• Test owner sign-in flow with each role option"Dally - Platrorm• om lert100% 2. Mon 18 May 9:59:27AskJiminnyReportActivityServiceTest v+0 ..Condition: v-ir="!Tlags. teamcreated"Modify UserInvitationDT0:: for0wner() to use selected role + AdminMove Opportunity Sync Period, add role field in its placesame component handles bothwCal aAsk anvthina &4DSWF.16WN Windsurf Teams200-22 UTF.8Po 4 spaces...
|
49805
|
NULL
|
NULL
|
NULL
|
|
49806
|
1769
|
58
|
2026-05-18T06:59:28.157940+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087568157_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
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 left100% C8• Mon 18 May 9:59:28Nikolay Yankov (Presenting)AA+9TátM InbKioskOrganizationsSetup AccountAite XIxMxsxошxахохотхокхоро х0SGФ:00 J xlOa x O*8• Mon 18 May 9:50YSRXxJm x83 Pro: https://app.jiminny.com/kiosk/onboard-istProjectsE3 SSH• Home | Salestorcet Clauớeecroeclan senayXL Lasasinsignts & Coachn.0 DevwamareAutomated ReportsMobile verssonNikolay YankovLukas Kovalik9:59 AM ||Daily - Platform• 13:02|Lộ3...
|
NULL
|
6217639656280240795
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsW FirefoxFileEdit→ViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 6 m left100% C8• Mon 18 May 9:59:28Nikolay Yankov (Presenting)AA+9TátM InbKioskOrganizationsSetup AccountAite XIxMxsxошxахохотхокхоро х0SGФ:00 J xlOa x O*8• Mon 18 May 9:50YSRXxJm x83 Pro: https://app.jiminny.com/kiosk/onboard-istProjectsE3 SSH• Home | Salestorcet Clauớeecroeclan senayXL Lasasinsignts & Coachn.0 DevwamareAutomated ReportsMobile verssonNikolay YankovLukas Kovalik9:59 AM ||Daily - Platform• 13:02|Lộ3...
|
49804
|
NULL
|
NULL
|
NULL
|
|
49808
|
1769
|
59
|
2026-05-18T06:59:31.215257+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087571215_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
-5144026249968099006
|
1739586043254377858
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpDaily - Platform - 6 m left100% <78• Mon 18 May 9:59:31meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com=+Q10.SNikolay Yankov (Presenting)TdtKioskOrganizationsSetup AtcouncAulomiaked KeoortsMobile versionAn 3TabE3 JmX PrO•.G0Aitc XIx* XSh x UCu x *0a xCosXum xoMo x9Pо xI0 Jm x l0c xDataosdA serdy XX blasinsignts & Coachn.0 DevSetup Account|General|LocienCALENCARTiers & Add-ons8• Mon 18 May 9:59L Al BookmarxsNAMEchtinsХанurіnYardstidYCD MutimadaZilion fechnolopies, lncXDimensional TechnoiogelZeohvrZineZimbeaYalantisZiliantXebiatabsXypro TechecloryZeeax. LLCXyfeme, Ine.Wyene SistennSFDC ACCOUNT0011/K000022853 VQAW0011K0000228SPLOM0011KO000228SPMOM0011K0000228SPNOAS0011K00002285PPQ410011K00002285PQOAD011.K0000220SPSCM0011K00002285PTOA10011K0000228SPUOAN0011K0000228SPVQM001.1K0000228SPWQA0011X0000228SPXQA40011K0000228SPYOAX0011KD000228SPJQAOJiminny VoiceIlers crolainsdNikolay YankovLukas Kovalik9:59 AM | Daily - Platform13:05...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49809
|
1769
|
60
|
2026-05-18T06:59:34.211680+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087574211_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v2\Api\ActivitiesApi;
use Pipedrive\versions\v2\Api\ActivityFieldsApi;
use Pipedrive\versions\v2\Api\DealFieldsApi;
use Pipedrive\versions\v2\Api\DealsApi;
use Pipedrive\versions\v2\Api\PersonFieldsApi;
use Pipedrive\versions\v2\Api\PersonsApi;
use Pipedrive\versions\v2\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$this->info('Test 2a: Get Deals');
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// v2 SDK might have different method names
// Try common v2 method names
try {
$result = $apiInstance->getDeals(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', true, "Retrieved deals in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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":"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,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.02013889,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"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\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v2\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v2\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v2\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $this->info('Test 2a: Get Deals');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // v2 SDK might have different method names\n // Try common v2 method names\n try {\n $result = $apiInstance->getDeals(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', true, \"Retrieved deals in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method\n $result = $apiInstance->getDealsSummary();\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v2\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v2\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v2\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $this->info('Test 2a: Get Deals');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // v2 SDK might have different method names\n // Try common v2 method names\n try {\n $result = $apiInstance->getDeals(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', true, \"Retrieved deals in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method\n $result = $apiInstance->getDealsSummary();\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\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}]...
|
6169410896797108
|
25623949094578836
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v2\Api\ActivitiesApi;
use Pipedrive\versions\v2\Api\ActivityFieldsApi;
use Pipedrive\versions\v2\Api\DealFieldsApi;
use Pipedrive\versions\v2\Api\DealsApi;
use Pipedrive\versions\v2\Api\PersonFieldsApi;
use Pipedrive\versions\v2\Api\PersonsApi;
use Pipedrive\versions\v2\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$this->info('Test 2a: Get Deals');
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// v2 SDK might have different method names
// Try common v2 method names
try {
$result = $apiInstance->getDeals(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', true, "Retrieved deals in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
49808
|
NULL
|
NULL
|
NULL
|
|
49810
|
1769
|
61
|
2026-05-18T06:59:37.228514+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087577228_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v2\Api\ActivitiesApi;
use Pipedrive\versions\v2\Api\ActivityFieldsApi;
use Pipedrive\versions\v2\Api\DealFieldsApi;
use Pipedrive\versions\v2\Api\DealsApi;
use Pipedrive\versions\v2\Api\PersonFieldsApi;
use Pipedrive\versions\v2\Api\PersonsApi;
use Pipedrive\versions\v2\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$this->info('Test 2a: Get Deals');
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// v2 SDK might have different method names
// Try common v2 method names
try {
$result = $apiInstance->getDeals(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', true, "Retrieved deals in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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":"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,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.02013889,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"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\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v2\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v2\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v2\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $this->info('Test 2a: Get Deals');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // v2 SDK might have different method names\n // Try common v2 method names\n try {\n $result = $apiInstance->getDeals(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', true, \"Retrieved deals in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method\n $result = $apiInstance->getDealsSummary();\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v2\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v2\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v2\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $this->info('Test 2a: Get Deals');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // v2 SDK might have different method names\n // Try common v2 method names\n try {\n $result = $apiInstance->getDeals(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', true, \"Retrieved deals in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method\n $result = $apiInstance->getDealsSummary();\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\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}]...
|
7869633438160526668
|
25623949094578836
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v2\Api\ActivitiesApi;
use Pipedrive\versions\v2\Api\ActivityFieldsApi;
use Pipedrive\versions\v2\Api\DealFieldsApi;
use Pipedrive\versions\v2\Api\DealsApi;
use Pipedrive\versions\v2\Api\PersonFieldsApi;
use Pipedrive\versions\v2\Api\PersonsApi;
use Pipedrive\versions\v2\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$this->info('Test 2a: Get Deals');
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// v2 SDK might have different method names
// Try common v2 method names
try {
$result = $apiInstance->getDeals(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', true, "Retrieved deals in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49812
|
NULL
|
0
|
2026-05-18T06:59:42.038302+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087582038_m2.jpg...
|
PhpStorm
|
faVsco.js – ~/jiminny/app/front-end/src/components faVsco.js – ~/jiminny/app/front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.05618351,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
7266624862028544203
|
577591577001045378
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
iilPhostormVIewINavicareCodeLaravelKeractorFV faVsco.js°° pipedrive-sdk-pocProiect vlooolsude> D build> D config>@ contrib> @ database>@ docsv @ front-end• .vscode› O.yarn• → coverage› _ node_modules>L publicresourcesu scriotsW sromassetsN comoonents• M AiRenortsM connectD dashboardD DealinsightsM erorDadedM eynort-nortaleytension-installedM Invitationlaelaaleailelealeeonboard→ olavoackolavlistsv Settinas• Mtests_• M ActivitiesSearch• → AutomatedReports> M MobileAorv D modalsv M EditTeamModall• M tects |C ActivityController.ongconvertLeadActivitles.ongsyncriannat.ongc createrlaybookcreatedevent.ongc) IntearationApp/Service.php© LeadConverted.phd© CreateSelfCoachedEvent.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohp© PlanhatActivityListener.php(C)AskAnvthinaPromotService.ohd(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.oho/(C) AutomatedReportkesultonp(C) AutomatedRenort.ohrEditTeamModal.vue XKtemplate:<AppDrawerModal v-bind="drawerAttrs" #default="{ $style: drawerStyle }">ediv •clacc-iidnawenStvlo formGnidil,<div :class="drawerStyle.sectionTitle">General</div><AppFormFieldfield-label="Company name'v-model="tormstate.name"required="true"rules="reouzreddata-testid="setun-trial-name"<-- Owner Emanl --,<ApoFormFieldv-ife"flaas. ownercreated"tvne="emanl"field-label="Owner Fmail"V-model="formState ownen emai]"reaurrede"true"name="ownen email"rules="required|email"data-tectid="cetun-tnial-ounen-oma.l"<AppFormFieldv-elsefield-lahel="Nwnen"name="ownen idu:required="true'rules="requ1red"v-model="formState.owner_ id"options="formData.admins.data 11 []":Loading="formbata.admins.loading"tyoe="selontnV EditTeamAddreccFields vueVCditToamModal vuatrack-bv="1d"is fonturoc icdata-testid="setup-trial-owner-emar"V FeaturesGroup.vueolner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (25 minutes aao)=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmuse Pipedrive verszons vz Ap1 ACCIV1CleSAp1use Pipedrive\versions\v2\Api ActivityFieldsApi:use Pipedrave versions vz Ap1 Leaurielasapluse Pipedrive\versions\v2 \Api\DealsApi:use Pipearive versions vz Ap1 Personrlelasapluse Pipedrive verszons Vz Ap1 Personsap1.use Pipeorive verszonsvz contzquracion:11 usage22124 6t26 6t32 đprotected Ssignature = "11minnv:test-p1pedrive-officral-sok teamid-'*protected Sdescrintion = ITest official Pinednive SDK (oinedrive/pinednive) with exiorivate arrav Sresults =1lusageprivate EncryptedTokenManager $tokenManager:no usagespublic function __construct(EncryptedTokenManager $tokenManager)parent:: construct?).sthls->cokennanager = Scokenmanager;public function handled: intf...}private function runTests(int SteamId): void{...}1 usageprivate function testOAuthInitialization(SocialAccount SsocialAccount): voidf...?11 usageorivate function testBasicCrudOperations(SocialAccount SsocialAccount: void$this->info( string: 'Test 2: Basic CRUD Operations'):tny-Il Get the naw token from datahaseSnawhhToken = ScocialAccount->ae+ProviderilsenToken0•.strlen(SrawDbToken)."")•Trial Owner Role SelecNot Shown when editingModal used for botn create/editOwner gets selected role + AdminAlways gets Admin + RecorderKeplace Uppontuniy sync Perlod locatlolCurrently at lines 71-84Part of Create TeamHandled in EditTeamModalImplementation PlanFrontend Changes1. EditTeamModal.vue• Add role selection field below Owner email (after line 39Onlv show when creatina team ( Iflaas.teamGreated )• Move Opportunity Sync Period field to 3rd row, 1st column (after CRM field)Add role options: Recorder, Recorder & Voice, Analyst• Add owner role to form state1. CreateTeamRequest.oho• Add validation rule for ouner role field• Allowed values: recorder, recorder and voice, analyst• Onlv required when creatina (not editina)2. UserinvitationDTO::forOwner()• Accept owner_role parameter from request• Map role name to role IDAlways add ROLE_ADMIN to the role IDs (as per requirement: "selected role + Admin permissions")• Replace hardcoded ROLE RECORDER with selected role3. EditTeamRequest.oho• Ensure ouner role is NOT acceoted when editina (validation should reiect it)Key Files to Modify1. /front phoditreamModal/Ed1tTeamModal.vue2./aoo/Htto/Requests/Settinas/Teams/CreateTeamRequest.ohv3./app/DT0/Inv1tation/UserInv1tat1onDT0.php4./apo/Htto/Requests/Settinas/Teams/EditTeamRequest.ohoTectina Considerationc•Test role assignment for all 3 options (Recorder, Recorder & Voice, Analyst)Verity Admin permission is alwavs addedEnsure field is hidden when editing existing team• Verify Opportunity Sync Period moves to correct location• Test owner sign-in flow with each role option"Dally - Platrorm• om lert100% 2. Mon 18 May 9:59:41AskJiminnyReportActivityServiceTest v+0 ..Condition: v-ir="!Tlags. teamcreated"Modify UserInvitationDT0:: for0wner() to use selected role + AdminMove Opportunity Sync Period, add role field in its placeSame component handles bothAsk anvthina (&4-L)SWF.16Cal aW Windsurf Team1-1.UTE.8Po 2 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49811
|
1769
|
62
|
2026-05-18T06:59:43.298546+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087583298_m1.jpg...
|
PhpStorm
|
faVsco.js – ~/jiminny/app/front-end/src/components faVsco.js – ~/jiminny/app/front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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
Analyzing…
<template>
<AppDrawerModal v-bind="drawerAttrs" #default="{ $style: drawerStyle }">
<div :class="drawerStyle.formGrid">
<div :class="drawerStyle.sectionTitle">General</div>
<!-- Name -->
<AppFormField
field-label="Company name"
v-model="formState.name"
:required="true"
name="name"
rules="required"
data-testid="setup-trial-name"
/>
<!-- Owner Email -->
<AppFormField
v-if="!flags.ownerCreated"
type="email"
field-label="Owner Email"
v-model="formState.owner_email"
:required="true"
name="owner_email"
rules="required|email"
data-testid="setup-trial-owner-email"
/>
<AppFormField
v-else
field-label="Owner"
name="owner_id"
:required="true"
rules="required"
v-model="formState.owner_id"
:options="formData.admins.data || []"
:loading="formData.admins.loading"
type="select"
option-label="name"
track-by="id"
data-testid="setup-trial-owner-email"
/>
<!-- CRM -->
<AppFormField
v-model="formState.crm"
name="crm"
type="select"
field-label="CRM"
:required="true"
rules="required"
:options="formData.crmOptions.data || []"
track-by="id"
option-label="label"
:loading="formData.crmOptions.loading"
data-testid="setup-trial-crm"
:disabled="flags.ownerCreated"
/>
<!-- Partner (only shown to default-partner kiosk users in edit mode who have access to multiple partners) -->
<AppFormField
v-if="flags.teamCreated && formData.partners.data?.length > 1"
v-model="formState.partner_id"
name="partner_id"
type="select"
field-label="Partner"
:options="formData.partners.data || []"
track-by="id"
option-label="name"
:loading="formData.partners.loading"
data-testid="setup-trial-partner"
/>
<!-- Opportunity Sync Period -->
<AppFormField
:disabled="!requireSyncPeriod"
v-model="formState.opportunity_sync_period"
name="opportunity_sync_period"
type="select"
field-label="Import Opportunities Sync Period"
:required="requireSyncPeriod"
:rules="requireSyncPeriod ? 'required' : ''"
:options="syncPeriodOptions"
track-by="id"
option-label="label"
data-testid="setup-trial-sync-period"
/>
<!-- Calendar -->
<AppFormField
v-model="formState.calendar"
name="calendar"
type="radios"
ui="radios"
field-label="Calendar"
:required="true"
rules="required"
:options="formData.calendarOptions.data || []"
data-testid="setup-trial-calendar"
:disabled="flags.ownerCreated"
/>
<!-- Softphone -->
<div>
<div :class="[$style.fieldLabel, drawerStyle.fieldLabel]">
Softphone
</div>
<AppFormField
v-model="formState.features"
name="softphone"
type="checkbox"
:value="SOFTPHONE_FEATURE_ID"
:field-label="jiminnyVoiceLabel"
data-testid="setup-trial-softphone"
/>
</div>
<EditTeamAddressFields
v-if="softphoneEnabled"
:disabled="flags.billingDisabled"
/>
</div>
<div :class="$style.tearsGrid">
<div :class="$style.sectionTitle">
<div :class="drawerStyle.sectionTitle">Tiers & Add-ons</div>
<AppButton
icon="question"
label="Tiers explained"
mods="seamless link primary"
href="[URL_WITH_CREDENTIALS]
import useAppForm, {
SilentFormError,
} from "@/components/shared/AppFormElements/useAppForm";
import AppForm from "@/components/shared/AppFormElements/AppForm.vue";
import AppFormField from "@/components/shared/AppFormElements/AppFormField.vue";
import useAsyncData from "@/composables/useAsyncData";
import EditTeamAddressFields from "./EditTeamAddressFields.vue";
import AppDrawerModal from "@/components/shared/modals/AppDrawerModal.vue";
import { useDrawerModal } from "@/composables/useDrawerModal";
import { promptModal } from "jenesius-vue-modal";
import ChangeOwnerConfirmModal from "@/components/Settings/OrgSettings/Members/ChangeOwnerConfirmModal.vue";
import EventBus from "@/utils/event-bus";
import { getFeaturesData } from "./features";
import FeaturesGroup from "./FeaturesGroup.vue";
import FeaturesList from "./FeaturesList.vue";
import { ErrorMessage, useField } from "vee-validate";
import AppButton from "@/components/shared/Buttons/AppButton.vue";
import { useBrandedI18n } from "@/composables/useBrandedI18n";
// Define props
const props = defineProps({
data: {
type: Object,
required: true,
},
teamId: String,
});
const { tb } = useBrandedI18n();
// Branded i18n computed ref
const jiminnyVoiceLabel = tb("kiosk.edit-team.jiminny-voice--whitelabel");
const flags = reactive({
teamCreated: computed(() => !!props.data.id),
ownerCreated: computed(() => !!props.data.owner_id),
billingDisabled: computed(
() =>
!!props.data.id && props.data?.features?.includes(SOFTPHONE_FEATURE_ID),
),
});
// Setup form
const form = useAppForm({
onSubmit,
toastSuccess: flags.teamCreated
? "Account updated successfully!"
: "Account created successfully!",
});
// Setup form state with initial values
const {
formState,
hasChanges,
updateSnapshot,
exportFormState,
softphoneEnabled,
} = useEditTeamForm(props.data);
// Load required data
const formData = reactive({
calendarOptions: useAsyncData(getCalendars, { showError: true }),
crmOptions: useAsyncData(getCrmServices, { showError: true }),
features: useAsyncData(getFeaturesData, { showError: true }),
partners: useAsyncData(getPartners, { showError: true }),
admins: reactive(useAdminsList()),
});
const { close } = useDrawerModal({ onClose });
const { tierModel, featuresGroups } = useFeaturesManager();
const { requireSyncPeriod } = useRequireSyncPeriod();
const drawerAttrs = computed(() => ({
as: AppForm,
title: flags.teamCreated ? "Edit Organization" : "Setup Account",
headerButtons: [
{
type: "submit",
label: "Save",
variant: "primary",
"data-testid": "setup-trial-submit",
disabled: !unref(hasChanges),
},
],
contentAttrs: {
busy: Object.values(formData).some(({ loading }) => loading),
},
}));
function onClose() {
return modalDiscardGuard({
onSave: form.submitHandler,
hasChanges: unref(hasChanges),
});
}
async function onSubmit() {
const ownerChanged =
flags.ownerCreated && formState.value.owner_id !== props.data.owner_id;
if (ownerChanged) {
const confirmed = await promptModal(ChangeOwnerConfirmModal);
if (!confirmed) throw new SilentFormError("Owner change not confirmed");
}
const data = exportFormState();
// create or update the team
!flags.teamCreated
? await axios.post("/api/v1/settings/organizations", data)
: await axios.put(`/api/v1/kiosk/organizations/${props.data.id}`, data);
EventBus.$emit("team.updated");
// update form snapshot
updateSnapshot();
close();
}
function useFeaturesManager() {
const tierField = useField("tier_id", "required", {
initialValue: unref(formState).tier_id,
});
const tierModel = computed({
get() {
return unref(formState).tier_id;
},
set(tierId) {
setTier(tierId);
tierField.value.value = tierId;
},
});
const featuresGroups = computed(() => {
const { groups } = formData.features.data || {};
if (!groups) return [];
return [groups.TIER, groups["ADD_ON"]].filter(Boolean).flat();
});
function setTier(tierId) {
const selectedFeatures = new Set(unref(formState).features);
const { features, tiers } = formData.features.data;
// clear all tier features
features.byType.TIER.forEach(({ id }) => selectedFeatures.delete(id));
const tier = tiers.find((tier) => tier.id === tierId);
// select only selected tiers features
[...tier.inherits, tierId]
.map((tierId) => features.byTier[tierId] || [])
.flat()
.forEach((feature) => selectedFeatures.add(feature.id));
Object.assign(unref(formState), {
features: Array.from(selectedFeatures),
tier_id: tierId,
});
}
return { tierModel, setTier, featuresGroups };
}
function useRequireSyncPeriod() {
// Computed property to check if opportunity sync period is required
const requireSyncPeriod = computed(() => {
return !!formData.crmOptions.data?.find(
(item) => formState.value.crm === item.id,
)?.requireInitialSyncPeriod;
});
watch(requireSyncPeriod, (required) => {
formState.value.opportunity_sync_period = required
? formState.value.opportunity_sync_period ||
DEFAULT_OPPORTUNITY_SYNC_PERIOD
: null;
});
return { requireSyncPeriod };
}
function useAdminsList() {
return useAsyncData(async () => {
const data = await fetchUsersData(props.data.id);
return data.filter((user) => user.roles?.some((e) => e.name == "admin"));
});
}
</script>
<style lang="less" module>
.fieldLabel:has(~ * :disabled) {
opacity: 0.6;
}
.tearsGrid {
display: grid;
padding-top: 10px;
gap: 10px;
.sectionTitle {
margin-top: 30px;
display: flex;
justify-content: space-between;
}
}
.errorMessage {
color: var(--color-danger);
}
.docsRef {
font-size: 14px;
}
</style>
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v2\Api\ActivitiesApi;
use Pipedrive\versions\v2\Api\ActivityFieldsApi;
use Pipedrive\versions\v2\Api\DealFieldsApi;
use Pipedrive\versions\v2\Api\DealsApi;
use Pipedrive\versions\v2\Api\PersonFieldsApi;
use Pipedrive\versions\v2\Api\PersonsApi;
use Pipedrive\versions\v2\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$this->info('Test 2a: Get Deals');
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// v2 SDK might have different method names
// Try common v2 method names
try {
$result = $apiInstance->getDeals(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', true, "Retrieved deals in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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":"AXStaticText","text":"Analyzing…","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"<template>\n <AppDrawerModal v-bind=\"drawerAttrs\" #default=\"{ $style: drawerStyle }\">\n <div :class=\"drawerStyle.formGrid\">\n <div :class=\"drawerStyle.sectionTitle\">General</div>\n <!-- Name -->\n <AppFormField\n field-label=\"Company name\"\n v-model=\"formState.name\"\n :required=\"true\"\n name=\"name\"\n rules=\"required\"\n data-testid=\"setup-trial-name\"\n />\n\n <!-- Owner Email -->\n <AppFormField\n v-if=\"!flags.ownerCreated\"\n type=\"email\"\n field-label=\"Owner Email\"\n v-model=\"formState.owner_email\"\n :required=\"true\"\n name=\"owner_email\"\n rules=\"required|email\"\n data-testid=\"setup-trial-owner-email\"\n />\n <AppFormField\n v-else\n field-label=\"Owner\"\n name=\"owner_id\"\n :required=\"true\"\n rules=\"required\"\n v-model=\"formState.owner_id\"\n :options=\"formData.admins.data || []\"\n :loading=\"formData.admins.loading\"\n type=\"select\"\n option-label=\"name\"\n track-by=\"id\"\n data-testid=\"setup-trial-owner-email\"\n />\n\n <!-- CRM -->\n <AppFormField\n v-model=\"formState.crm\"\n name=\"crm\"\n type=\"select\"\n field-label=\"CRM\"\n :required=\"true\"\n rules=\"required\"\n :options=\"formData.crmOptions.data || []\"\n track-by=\"id\"\n option-label=\"label\"\n :loading=\"formData.crmOptions.loading\"\n data-testid=\"setup-trial-crm\"\n :disabled=\"flags.ownerCreated\"\n />\n\n <!-- Partner (only shown to default-partner kiosk users in edit mode who have access to multiple partners) -->\n <AppFormField\n v-if=\"flags.teamCreated && formData.partners.data?.length > 1\"\n v-model=\"formState.partner_id\"\n name=\"partner_id\"\n type=\"select\"\n field-label=\"Partner\"\n :options=\"formData.partners.data || []\"\n track-by=\"id\"\n option-label=\"name\"\n :loading=\"formData.partners.loading\"\n data-testid=\"setup-trial-partner\"\n />\n\n <!-- Opportunity Sync Period -->\n <AppFormField\n :disabled=\"!requireSyncPeriod\"\n v-model=\"formState.opportunity_sync_period\"\n name=\"opportunity_sync_period\"\n type=\"select\"\n field-label=\"Import Opportunities Sync Period\"\n :required=\"requireSyncPeriod\"\n :rules=\"requireSyncPeriod ? 'required' : ''\"\n :options=\"syncPeriodOptions\"\n track-by=\"id\"\n option-label=\"label\"\n data-testid=\"setup-trial-sync-period\"\n />\n\n <!-- Calendar -->\n <AppFormField\n v-model=\"formState.calendar\"\n name=\"calendar\"\n type=\"radios\"\n ui=\"radios\"\n field-label=\"Calendar\"\n :required=\"true\"\n rules=\"required\"\n :options=\"formData.calendarOptions.data || []\"\n data-testid=\"setup-trial-calendar\"\n :disabled=\"flags.ownerCreated\"\n />\n\n <!-- Softphone -->\n <div>\n <div :class=\"[$style.fieldLabel, drawerStyle.fieldLabel]\">\n Softphone\n </div>\n <AppFormField\n v-model=\"formState.features\"\n name=\"softphone\"\n type=\"checkbox\"\n :value=\"SOFTPHONE_FEATURE_ID\"\n :field-label=\"jiminnyVoiceLabel\"\n data-testid=\"setup-trial-softphone\"\n />\n </div>\n\n <EditTeamAddressFields\n v-if=\"softphoneEnabled\"\n :disabled=\"flags.billingDisabled\"\n />\n\n </div>\n <div :class=\"$style.tearsGrid\">\n <div :class=\"$style.sectionTitle\">\n <div :class=\"drawerStyle.sectionTitle\">Tiers & Add-ons</div>\n <AppButton\n icon=\"question\"\n label=\"Tiers explained\"\n mods=\"seamless link primary\"\n href=\"https://jiminny.atlassian.net/wiki/external/OGRhNWI0NzJjZTc0NDg1YTg5MTU4NGYwZWU3NTc2OGM\"\n :class=\"$style.docsRef\"\n />\n </div>\n <ErrorMessage name=\"tier_id\">\n <div :class=\"$style.errorMessage\">Selecting tier is required</div>\n </ErrorMessage>\n <FeaturesGroup\n v-for=\"group in featuresGroups\"\n :key=\"group.tier?.id || group.type\"\n v-bind=\"{ group, tiers: formData.features.data.tiers }\"\n v-model:tier=\"tierModel\"\n v-model:features=\"formState.features\"\n />\n <template\n v-if=\"\n flags.teamCreated &&\n formData.features.data?.features.byType.DEV?.length\n \"\n >\n <div :class=\"[$style.sectionTitle, drawerStyle.sectionTitle]\">\n Technical Settings\n </div>\n <FeaturesList\n v-model=\"formState.features\"\n :features=\"formData.features.data.features.byType.DEV\"\n />\n </template>\n </div>\n </AppDrawerModal>\n</template>\n<script>\nconst SOFTPHONE_FEATURE_ID = \"DIALER\";\n\n// Options for opportunity sync period\nconst syncPeriodOptions = [\n { id: \"3m\", label: \"3 Months\" },\n { id: \"6m\", label: \"6 Months\" },\n { id: \"12m\", label: \"12 Months\" },\n];\n\nconst DEFAULT_OPPORTUNITY_SYNC_PERIOD = syncPeriodOptions[0].id;\n\nexport const useEditTeamForm = toSelfProvidingHook((data) => {\n const formState = ref({\n features: [],\n ...data,\n });\n\n const formStateSnapshot = ref();\n\n updateSnapshot();\n\n const hasChanges = computed(\n () => !isEqual(formState.value, formStateSnapshot.value),\n );\n\n const softphoneEnabled = computed(() =>\n unref(formState).features?.includes(SOFTPHONE_FEATURE_ID),\n );\n\n function exportFormState() {\n const excluded = [\"softphone\"];\n\n if (!unref(softphoneEnabled)) {\n excluded.push(\"address\", \"city\", \"state\", \"zip\", \"country\");\n }\n\n return omit(formState.value, excluded);\n }\n\n function updateSnapshot() {\n formStateSnapshot.value = cloneDeep(formState.value);\n }\n\n return {\n formState,\n updateSnapshot,\n hasChanges,\n exportFormState,\n softphoneEnabled,\n };\n});\n\n// Data loading functions\nasync function getCalendars() {\n const { error, data } = await tryCatch(axios.get(\"/api/v1/calendars\"));\n\n if (!error) return data.data.map(({ id, label }) => ({ value: id, label }));\n\n console.error(error);\n throw new Error(\"Error loading calendars\");\n}\n\nasync function getCrmServices() {\n const { error, data } = await tryCatch(axios.get(\"/api/v1/crm-services\"));\n if (!error) return Object.values(data.data);\n\n console.error(error);\n throw new Error(\"Error loading CRM services\");\n}\n\nasync function getPartners() {\n const { error, data } = await tryCatch(\n axios.get(\"/api/v1/kiosk/partners\"),\n );\n if (!error) return data.data.data;\n\n console.error(error);\n throw new Error(\"Error loading partners\");\n}\n\nasync function fetchUsersData(teamId) {\n const { data, status } = await axios.get(\n `/api/v1/kiosk/organizations/${teamId}/users`,\n );\n\n if (status === 200) {\n return data;\n } else {\n throw new Error(\"Error in fetching users data\");\n }\n}\n</script>\n<script setup>\nimport { computed, ref, reactive, watch, unref } from \"vue\";\nimport axios from \"axios\";\nimport { cloneDeep, isEqual, omit } from \"lodash-es\";\nimport { modalDiscardGuard, toSelfProvidingHook, tryCatch } from \"@/utils\";\nimport useAppForm, {\n SilentFormError,\n} from \"@/components/shared/AppFormElements/useAppForm\";\nimport AppForm from \"@/components/shared/AppFormElements/AppForm.vue\";\nimport AppFormField from \"@/components/shared/AppFormElements/AppFormField.vue\";\nimport useAsyncData from \"@/composables/useAsyncData\";\nimport EditTeamAddressFields from \"./EditTeamAddressFields.vue\";\nimport AppDrawerModal from \"@/components/shared/modals/AppDrawerModal.vue\";\nimport { useDrawerModal } from \"@/composables/useDrawerModal\";\nimport { promptModal } from \"jenesius-vue-modal\";\nimport ChangeOwnerConfirmModal from \"@/components/Settings/OrgSettings/Members/ChangeOwnerConfirmModal.vue\";\nimport EventBus from \"@/utils/event-bus\";\nimport { getFeaturesData } from \"./features\";\nimport FeaturesGroup from \"./FeaturesGroup.vue\";\nimport FeaturesList from \"./FeaturesList.vue\";\nimport { ErrorMessage, useField } from \"vee-validate\";\nimport AppButton from \"@/components/shared/Buttons/AppButton.vue\";\nimport { useBrandedI18n } from \"@/composables/useBrandedI18n\";\n\n// Define props\nconst props = defineProps({\n data: {\n type: Object,\n required: true,\n },\n teamId: String,\n});\n\nconst { tb } = useBrandedI18n();\n\n// Branded i18n computed ref\nconst jiminnyVoiceLabel = tb(\"kiosk.edit-team.jiminny-voice--whitelabel\");\n\nconst flags = reactive({\n teamCreated: computed(() => !!props.data.id),\n ownerCreated: computed(() => !!props.data.owner_id),\n billingDisabled: computed(\n () =>\n !!props.data.id && props.data?.features?.includes(SOFTPHONE_FEATURE_ID),\n ),\n});\n\n// Setup form\nconst form = useAppForm({\n onSubmit,\n toastSuccess: flags.teamCreated\n ? \"Account updated successfully!\"\n : \"Account created successfully!\",\n});\n\n// Setup form state with initial values\nconst {\n formState,\n hasChanges,\n updateSnapshot,\n exportFormState,\n softphoneEnabled,\n} = useEditTeamForm(props.data);\n\n// Load required data\nconst formData = reactive({\n calendarOptions: useAsyncData(getCalendars, { showError: true }),\n crmOptions: useAsyncData(getCrmServices, { showError: true }),\n features: useAsyncData(getFeaturesData, { showError: true }),\n partners: useAsyncData(getPartners, { showError: true }),\n admins: reactive(useAdminsList()),\n});\n\nconst { close } = useDrawerModal({ onClose });\n\nconst { tierModel, featuresGroups } = useFeaturesManager();\n\nconst { requireSyncPeriod } = useRequireSyncPeriod();\n\nconst drawerAttrs = computed(() => ({\n as: AppForm,\n title: flags.teamCreated ? \"Edit Organization\" : \"Setup Account\",\n headerButtons: [\n {\n type: \"submit\",\n label: \"Save\",\n variant: \"primary\",\n \"data-testid\": \"setup-trial-submit\",\n disabled: !unref(hasChanges),\n },\n ],\n contentAttrs: {\n busy: Object.values(formData).some(({ loading }) => loading),\n },\n}));\n\nfunction onClose() {\n return modalDiscardGuard({\n onSave: form.submitHandler,\n hasChanges: unref(hasChanges),\n });\n}\n\nasync function onSubmit() {\n const ownerChanged =\n flags.ownerCreated && formState.value.owner_id !== props.data.owner_id;\n\n if (ownerChanged) {\n const confirmed = await promptModal(ChangeOwnerConfirmModal);\n if (!confirmed) throw new SilentFormError(\"Owner change not confirmed\");\n }\n\n const data = exportFormState();\n\n // create or update the team\n !flags.teamCreated\n ? await axios.post(\"/api/v1/settings/organizations\", data)\n : await axios.put(`/api/v1/kiosk/organizations/${props.data.id}`, data);\n\n EventBus.$emit(\"team.updated\");\n\n // update form snapshot\n updateSnapshot();\n close();\n}\n\nfunction useFeaturesManager() {\n const tierField = useField(\"tier_id\", \"required\", {\n initialValue: unref(formState).tier_id,\n });\n\n const tierModel = computed({\n get() {\n return unref(formState).tier_id;\n },\n set(tierId) {\n setTier(tierId);\n tierField.value.value = tierId;\n },\n });\n\n const featuresGroups = computed(() => {\n const { groups } = formData.features.data || {};\n\n if (!groups) return [];\n\n return [groups.TIER, groups[\"ADD_ON\"]].filter(Boolean).flat();\n });\n\n function setTier(tierId) {\n const selectedFeatures = new Set(unref(formState).features);\n const { features, tiers } = formData.features.data;\n\n // clear all tier features\n features.byType.TIER.forEach(({ id }) => selectedFeatures.delete(id));\n\n const tier = tiers.find((tier) => tier.id === tierId);\n\n // select only selected tiers features\n [...tier.inherits, tierId]\n .map((tierId) => features.byTier[tierId] || [])\n .flat()\n .forEach((feature) => selectedFeatures.add(feature.id));\n\n Object.assign(unref(formState), {\n features: Array.from(selectedFeatures),\n tier_id: tierId,\n });\n }\n\n return { tierModel, setTier, featuresGroups };\n}\n\nfunction useRequireSyncPeriod() {\n // Computed property to check if opportunity sync period is required\n const requireSyncPeriod = computed(() => {\n return !!formData.crmOptions.data?.find(\n (item) => formState.value.crm === item.id,\n )?.requireInitialSyncPeriod;\n });\n\n watch(requireSyncPeriod, (required) => {\n formState.value.opportunity_sync_period = required\n ? formState.value.opportunity_sync_period ||\n DEFAULT_OPPORTUNITY_SYNC_PERIOD\n : null;\n });\n\n return { requireSyncPeriod };\n}\n\nfunction useAdminsList() {\n return useAsyncData(async () => {\n const data = await fetchUsersData(props.data.id);\n\n return data.filter((user) => user.roles?.some((e) => e.name == \"admin\"));\n });\n}\n</script>\n\n<style lang=\"less\" module>\n.fieldLabel:has(~ * :disabled) {\n opacity: 0.6;\n}\n.tearsGrid {\n display: grid;\n padding-top: 10px;\n gap: 10px;\n .sectionTitle {\n margin-top: 30px;\n display: flex;\n justify-content: space-between;\n }\n}\n.errorMessage {\n color: var(--color-danger);\n}\n.docsRef {\n font-size: 14px;\n}\n</style>","depth":4,"on_screen":true,"value":"<template>\n <AppDrawerModal v-bind=\"drawerAttrs\" #default=\"{ $style: drawerStyle }\">\n <div :class=\"drawerStyle.formGrid\">\n <div :class=\"drawerStyle.sectionTitle\">General</div>\n <!-- Name -->\n <AppFormField\n field-label=\"Company name\"\n v-model=\"formState.name\"\n :required=\"true\"\n name=\"name\"\n rules=\"required\"\n data-testid=\"setup-trial-name\"\n />\n\n <!-- Owner Email -->\n <AppFormField\n v-if=\"!flags.ownerCreated\"\n type=\"email\"\n field-label=\"Owner Email\"\n v-model=\"formState.owner_email\"\n :required=\"true\"\n name=\"owner_email\"\n rules=\"required|email\"\n data-testid=\"setup-trial-owner-email\"\n />\n <AppFormField\n v-else\n field-label=\"Owner\"\n name=\"owner_id\"\n :required=\"true\"\n rules=\"required\"\n v-model=\"formState.owner_id\"\n :options=\"formData.admins.data || []\"\n :loading=\"formData.admins.loading\"\n type=\"select\"\n option-label=\"name\"\n track-by=\"id\"\n data-testid=\"setup-trial-owner-email\"\n />\n\n <!-- CRM -->\n <AppFormField\n v-model=\"formState.crm\"\n name=\"crm\"\n type=\"select\"\n field-label=\"CRM\"\n :required=\"true\"\n rules=\"required\"\n :options=\"formData.crmOptions.data || []\"\n track-by=\"id\"\n option-label=\"label\"\n :loading=\"formData.crmOptions.loading\"\n data-testid=\"setup-trial-crm\"\n :disabled=\"flags.ownerCreated\"\n />\n\n <!-- Partner (only shown to default-partner kiosk users in edit mode who have access to multiple partners) -->\n <AppFormField\n v-if=\"flags.teamCreated && formData.partners.data?.length > 1\"\n v-model=\"formState.partner_id\"\n name=\"partner_id\"\n type=\"select\"\n field-label=\"Partner\"\n :options=\"formData.partners.data || []\"\n track-by=\"id\"\n option-label=\"name\"\n :loading=\"formData.partners.loading\"\n data-testid=\"setup-trial-partner\"\n />\n\n <!-- Opportunity Sync Period -->\n <AppFormField\n :disabled=\"!requireSyncPeriod\"\n v-model=\"formState.opportunity_sync_period\"\n name=\"opportunity_sync_period\"\n type=\"select\"\n field-label=\"Import Opportunities Sync Period\"\n :required=\"requireSyncPeriod\"\n :rules=\"requireSyncPeriod ? 'required' : ''\"\n :options=\"syncPeriodOptions\"\n track-by=\"id\"\n option-label=\"label\"\n data-testid=\"setup-trial-sync-period\"\n />\n\n <!-- Calendar -->\n <AppFormField\n v-model=\"formState.calendar\"\n name=\"calendar\"\n type=\"radios\"\n ui=\"radios\"\n field-label=\"Calendar\"\n :required=\"true\"\n rules=\"required\"\n :options=\"formData.calendarOptions.data || []\"\n data-testid=\"setup-trial-calendar\"\n :disabled=\"flags.ownerCreated\"\n />\n\n <!-- Softphone -->\n <div>\n <div :class=\"[$style.fieldLabel, drawerStyle.fieldLabel]\">\n Softphone\n </div>\n <AppFormField\n v-model=\"formState.features\"\n name=\"softphone\"\n type=\"checkbox\"\n :value=\"SOFTPHONE_FEATURE_ID\"\n :field-label=\"jiminnyVoiceLabel\"\n data-testid=\"setup-trial-softphone\"\n />\n </div>\n\n <EditTeamAddressFields\n v-if=\"softphoneEnabled\"\n :disabled=\"flags.billingDisabled\"\n />\n\n </div>\n <div :class=\"$style.tearsGrid\">\n <div :class=\"$style.sectionTitle\">\n <div :class=\"drawerStyle.sectionTitle\">Tiers & Add-ons</div>\n <AppButton\n icon=\"question\"\n label=\"Tiers explained\"\n mods=\"seamless link primary\"\n href=\"https://jiminny.atlassian.net/wiki/external/OGRhNWI0NzJjZTc0NDg1YTg5MTU4NGYwZWU3NTc2OGM\"\n :class=\"$style.docsRef\"\n />\n </div>\n <ErrorMessage name=\"tier_id\">\n <div :class=\"$style.errorMessage\">Selecting tier is required</div>\n </ErrorMessage>\n <FeaturesGroup\n v-for=\"group in featuresGroups\"\n :key=\"group.tier?.id || group.type\"\n v-bind=\"{ group, tiers: formData.features.data.tiers }\"\n v-model:tier=\"tierModel\"\n v-model:features=\"formState.features\"\n />\n <template\n v-if=\"\n flags.teamCreated &&\n formData.features.data?.features.byType.DEV?.length\n \"\n >\n <div :class=\"[$style.sectionTitle, drawerStyle.sectionTitle]\">\n Technical Settings\n </div>\n <FeaturesList\n v-model=\"formState.features\"\n :features=\"formData.features.data.features.byType.DEV\"\n />\n </template>\n </div>\n </AppDrawerModal>\n</template>\n<script>\nconst SOFTPHONE_FEATURE_ID = \"DIALER\";\n\n// Options for opportunity sync period\nconst syncPeriodOptions = [\n { id: \"3m\", label: \"3 Months\" },\n { id: \"6m\", label: \"6 Months\" },\n { id: \"12m\", label: \"12 Months\" },\n];\n\nconst DEFAULT_OPPORTUNITY_SYNC_PERIOD = syncPeriodOptions[0].id;\n\nexport const useEditTeamForm = toSelfProvidingHook((data) => {\n const formState = ref({\n features: [],\n ...data,\n });\n\n const formStateSnapshot = ref();\n\n updateSnapshot();\n\n const hasChanges = computed(\n () => !isEqual(formState.value, formStateSnapshot.value),\n );\n\n const softphoneEnabled = computed(() =>\n unref(formState).features?.includes(SOFTPHONE_FEATURE_ID),\n );\n\n function exportFormState() {\n const excluded = [\"softphone\"];\n\n if (!unref(softphoneEnabled)) {\n excluded.push(\"address\", \"city\", \"state\", \"zip\", \"country\");\n }\n\n return omit(formState.value, excluded);\n }\n\n function updateSnapshot() {\n formStateSnapshot.value = cloneDeep(formState.value);\n }\n\n return {\n formState,\n updateSnapshot,\n hasChanges,\n exportFormState,\n softphoneEnabled,\n };\n});\n\n// Data loading functions\nasync function getCalendars() {\n const { error, data } = await tryCatch(axios.get(\"/api/v1/calendars\"));\n\n if (!error) return data.data.map(({ id, label }) => ({ value: id, label }));\n\n console.error(error);\n throw new Error(\"Error loading calendars\");\n}\n\nasync function getCrmServices() {\n const { error, data } = await tryCatch(axios.get(\"/api/v1/crm-services\"));\n if (!error) return Object.values(data.data);\n\n console.error(error);\n throw new Error(\"Error loading CRM services\");\n}\n\nasync function getPartners() {\n const { error, data } = await tryCatch(\n axios.get(\"/api/v1/kiosk/partners\"),\n );\n if (!error) return data.data.data;\n\n console.error(error);\n throw new Error(\"Error loading partners\");\n}\n\nasync function fetchUsersData(teamId) {\n const { data, status } = await axios.get(\n `/api/v1/kiosk/organizations/${teamId}/users`,\n );\n\n if (status === 200) {\n return data;\n } else {\n throw new Error(\"Error in fetching users data\");\n }\n}\n</script>\n<script setup>\nimport { computed, ref, reactive, watch, unref } from \"vue\";\nimport axios from \"axios\";\nimport { cloneDeep, isEqual, omit } from \"lodash-es\";\nimport { modalDiscardGuard, toSelfProvidingHook, tryCatch } from \"@/utils\";\nimport useAppForm, {\n SilentFormError,\n} from \"@/components/shared/AppFormElements/useAppForm\";\nimport AppForm from \"@/components/shared/AppFormElements/AppForm.vue\";\nimport AppFormField from \"@/components/shared/AppFormElements/AppFormField.vue\";\nimport useAsyncData from \"@/composables/useAsyncData\";\nimport EditTeamAddressFields from \"./EditTeamAddressFields.vue\";\nimport AppDrawerModal from \"@/components/shared/modals/AppDrawerModal.vue\";\nimport { useDrawerModal } from \"@/composables/useDrawerModal\";\nimport { promptModal } from \"jenesius-vue-modal\";\nimport ChangeOwnerConfirmModal from \"@/components/Settings/OrgSettings/Members/ChangeOwnerConfirmModal.vue\";\nimport EventBus from \"@/utils/event-bus\";\nimport { getFeaturesData } from \"./features\";\nimport FeaturesGroup from \"./FeaturesGroup.vue\";\nimport FeaturesList from \"./FeaturesList.vue\";\nimport { ErrorMessage, useField } from \"vee-validate\";\nimport AppButton from \"@/components/shared/Buttons/AppButton.vue\";\nimport { useBrandedI18n } from \"@/composables/useBrandedI18n\";\n\n// Define props\nconst props = defineProps({\n data: {\n type: Object,\n required: true,\n },\n teamId: String,\n});\n\nconst { tb } = useBrandedI18n();\n\n// Branded i18n computed ref\nconst jiminnyVoiceLabel = tb(\"kiosk.edit-team.jiminny-voice--whitelabel\");\n\nconst flags = reactive({\n teamCreated: computed(() => !!props.data.id),\n ownerCreated: computed(() => !!props.data.owner_id),\n billingDisabled: computed(\n () =>\n !!props.data.id && props.data?.features?.includes(SOFTPHONE_FEATURE_ID),\n ),\n});\n\n// Setup form\nconst form = useAppForm({\n onSubmit,\n toastSuccess: flags.teamCreated\n ? \"Account updated successfully!\"\n : \"Account created successfully!\",\n});\n\n// Setup form state with initial values\nconst {\n formState,\n hasChanges,\n updateSnapshot,\n exportFormState,\n softphoneEnabled,\n} = useEditTeamForm(props.data);\n\n// Load required data\nconst formData = reactive({\n calendarOptions: useAsyncData(getCalendars, { showError: true }),\n crmOptions: useAsyncData(getCrmServices, { showError: true }),\n features: useAsyncData(getFeaturesData, { showError: true }),\n partners: useAsyncData(getPartners, { showError: true }),\n admins: reactive(useAdminsList()),\n});\n\nconst { close } = useDrawerModal({ onClose });\n\nconst { tierModel, featuresGroups } = useFeaturesManager();\n\nconst { requireSyncPeriod } = useRequireSyncPeriod();\n\nconst drawerAttrs = computed(() => ({\n as: AppForm,\n title: flags.teamCreated ? \"Edit Organization\" : \"Setup Account\",\n headerButtons: [\n {\n type: \"submit\",\n label: \"Save\",\n variant: \"primary\",\n \"data-testid\": \"setup-trial-submit\",\n disabled: !unref(hasChanges),\n },\n ],\n contentAttrs: {\n busy: Object.values(formData).some(({ loading }) => loading),\n },\n}));\n\nfunction onClose() {\n return modalDiscardGuard({\n onSave: form.submitHandler,\n hasChanges: unref(hasChanges),\n });\n}\n\nasync function onSubmit() {\n const ownerChanged =\n flags.ownerCreated && formState.value.owner_id !== props.data.owner_id;\n\n if (ownerChanged) {\n const confirmed = await promptModal(ChangeOwnerConfirmModal);\n if (!confirmed) throw new SilentFormError(\"Owner change not confirmed\");\n }\n\n const data = exportFormState();\n\n // create or update the team\n !flags.teamCreated\n ? await axios.post(\"/api/v1/settings/organizations\", data)\n : await axios.put(`/api/v1/kiosk/organizations/${props.data.id}`, data);\n\n EventBus.$emit(\"team.updated\");\n\n // update form snapshot\n updateSnapshot();\n close();\n}\n\nfunction useFeaturesManager() {\n const tierField = useField(\"tier_id\", \"required\", {\n initialValue: unref(formState).tier_id,\n });\n\n const tierModel = computed({\n get() {\n return unref(formState).tier_id;\n },\n set(tierId) {\n setTier(tierId);\n tierField.value.value = tierId;\n },\n });\n\n const featuresGroups = computed(() => {\n const { groups } = formData.features.data || {};\n\n if (!groups) return [];\n\n return [groups.TIER, groups[\"ADD_ON\"]].filter(Boolean).flat();\n });\n\n function setTier(tierId) {\n const selectedFeatures = new Set(unref(formState).features);\n const { features, tiers } = formData.features.data;\n\n // clear all tier features\n features.byType.TIER.forEach(({ id }) => selectedFeatures.delete(id));\n\n const tier = tiers.find((tier) => tier.id === tierId);\n\n // select only selected tiers features\n [...tier.inherits, tierId]\n .map((tierId) => features.byTier[tierId] || [])\n .flat()\n .forEach((feature) => selectedFeatures.add(feature.id));\n\n Object.assign(unref(formState), {\n features: Array.from(selectedFeatures),\n tier_id: tierId,\n });\n }\n\n return { tierModel, setTier, featuresGroups };\n}\n\nfunction useRequireSyncPeriod() {\n // Computed property to check if opportunity sync period is required\n const requireSyncPeriod = computed(() => {\n return !!formData.crmOptions.data?.find(\n (item) => formState.value.crm === item.id,\n )?.requireInitialSyncPeriod;\n });\n\n watch(requireSyncPeriod, (required) => {\n formState.value.opportunity_sync_period = required\n ? formState.value.opportunity_sync_period ||\n DEFAULT_OPPORTUNITY_SYNC_PERIOD\n : null;\n });\n\n return { requireSyncPeriod };\n}\n\nfunction useAdminsList() {\n return useAsyncData(async () => {\n const data = await fetchUsersData(props.data.id);\n\n return data.filter((user) => user.roles?.some((e) => e.name == \"admin\"));\n });\n}\n</script>\n\n<style lang=\"less\" module>\n.fieldLabel:has(~ * :disabled) {\n opacity: 0.6;\n}\n.tearsGrid {\n display: grid;\n padding-top: 10px;\n gap: 10px;\n .sectionTitle {\n margin-top: 30px;\n display: flex;\n justify-content: space-between;\n }\n}\n.errorMessage {\n color: var(--color-danger);\n}\n.docsRef {\n font-size: 14px;\n}\n</style>","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,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.02013889,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"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\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v2\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v2\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v2\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $this->info('Test 2a: Get Deals');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // v2 SDK might have different method names\n // Try common v2 method names\n try {\n $result = $apiInstance->getDeals(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', true, \"Retrieved deals in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method\n $result = $apiInstance->getDealsSummary();\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v2\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v2\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v2\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $this->info('Test 2a: Get Deals');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // v2 SDK might have different method names\n // Try common v2 method names\n try {\n $result = $apiInstance->getDeals(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', true, \"Retrieved deals in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method\n $result = $apiInstance->getDealsSummary();\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\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},{"role":"AXStaticText","text":"app ~/jiminny/app, folder","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf, folder","depth":7,"on_screen":false,"role_description":"text"}]...
|
-8582840444965857068
|
25694249123465860
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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
Analyzing…
<template>
<AppDrawerModal v-bind="drawerAttrs" #default="{ $style: drawerStyle }">
<div :class="drawerStyle.formGrid">
<div :class="drawerStyle.sectionTitle">General</div>
<!-- Name -->
<AppFormField
field-label="Company name"
v-model="formState.name"
:required="true"
name="name"
rules="required"
data-testid="setup-trial-name"
/>
<!-- Owner Email -->
<AppFormField
v-if="!flags.ownerCreated"
type="email"
field-label="Owner Email"
v-model="formState.owner_email"
:required="true"
name="owner_email"
rules="required|email"
data-testid="setup-trial-owner-email"
/>
<AppFormField
v-else
field-label="Owner"
name="owner_id"
:required="true"
rules="required"
v-model="formState.owner_id"
:options="formData.admins.data || []"
:loading="formData.admins.loading"
type="select"
option-label="name"
track-by="id"
data-testid="setup-trial-owner-email"
/>
<!-- CRM -->
<AppFormField
v-model="formState.crm"
name="crm"
type="select"
field-label="CRM"
:required="true"
rules="required"
:options="formData.crmOptions.data || []"
track-by="id"
option-label="label"
:loading="formData.crmOptions.loading"
data-testid="setup-trial-crm"
:disabled="flags.ownerCreated"
/>
<!-- Partner (only shown to default-partner kiosk users in edit mode who have access to multiple partners) -->
<AppFormField
v-if="flags.teamCreated && formData.partners.data?.length > 1"
v-model="formState.partner_id"
name="partner_id"
type="select"
field-label="Partner"
:options="formData.partners.data || []"
track-by="id"
option-label="name"
:loading="formData.partners.loading"
data-testid="setup-trial-partner"
/>
<!-- Opportunity Sync Period -->
<AppFormField
:disabled="!requireSyncPeriod"
v-model="formState.opportunity_sync_period"
name="opportunity_sync_period"
type="select"
field-label="Import Opportunities Sync Period"
:required="requireSyncPeriod"
:rules="requireSyncPeriod ? 'required' : ''"
:options="syncPeriodOptions"
track-by="id"
option-label="label"
data-testid="setup-trial-sync-period"
/>
<!-- Calendar -->
<AppFormField
v-model="formState.calendar"
name="calendar"
type="radios"
ui="radios"
field-label="Calendar"
:required="true"
rules="required"
:options="formData.calendarOptions.data || []"
data-testid="setup-trial-calendar"
:disabled="flags.ownerCreated"
/>
<!-- Softphone -->
<div>
<div :class="[$style.fieldLabel, drawerStyle.fieldLabel]">
Softphone
</div>
<AppFormField
v-model="formState.features"
name="softphone"
type="checkbox"
:value="SOFTPHONE_FEATURE_ID"
:field-label="jiminnyVoiceLabel"
data-testid="setup-trial-softphone"
/>
</div>
<EditTeamAddressFields
v-if="softphoneEnabled"
:disabled="flags.billingDisabled"
/>
</div>
<div :class="$style.tearsGrid">
<div :class="$style.sectionTitle">
<div :class="drawerStyle.sectionTitle">Tiers & Add-ons</div>
<AppButton
icon="question"
label="Tiers explained"
mods="seamless link primary"
href="[URL_WITH_CREDENTIALS]
import useAppForm, {
SilentFormError,
} from "@/components/shared/AppFormElements/useAppForm";
import AppForm from "@/components/shared/AppFormElements/AppForm.vue";
import AppFormField from "@/components/shared/AppFormElements/AppFormField.vue";
import useAsyncData from "@/composables/useAsyncData";
import EditTeamAddressFields from "./EditTeamAddressFields.vue";
import AppDrawerModal from "@/components/shared/modals/AppDrawerModal.vue";
import { useDrawerModal } from "@/composables/useDrawerModal";
import { promptModal } from "jenesius-vue-modal";
import ChangeOwnerConfirmModal from "@/components/Settings/OrgSettings/Members/ChangeOwnerConfirmModal.vue";
import EventBus from "@/utils/event-bus";
import { getFeaturesData } from "./features";
import FeaturesGroup from "./FeaturesGroup.vue";
import FeaturesList from "./FeaturesList.vue";
import { ErrorMessage, useField } from "vee-validate";
import AppButton from "@/components/shared/Buttons/AppButton.vue";
import { useBrandedI18n } from "@/composables/useBrandedI18n";
// Define props
const props = defineProps({
data: {
type: Object,
required: true,
},
teamId: String,
});
const { tb } = useBrandedI18n();
// Branded i18n computed ref
const jiminnyVoiceLabel = tb("kiosk.edit-team.jiminny-voice--whitelabel");
const flags = reactive({
teamCreated: computed(() => !!props.data.id),
ownerCreated: computed(() => !!props.data.owner_id),
billingDisabled: computed(
() =>
!!props.data.id && props.data?.features?.includes(SOFTPHONE_FEATURE_ID),
),
});
// Setup form
const form = useAppForm({
onSubmit,
toastSuccess: flags.teamCreated
? "Account updated successfully!"
: "Account created successfully!",
});
// Setup form state with initial values
const {
formState,
hasChanges,
updateSnapshot,
exportFormState,
softphoneEnabled,
} = useEditTeamForm(props.data);
// Load required data
const formData = reactive({
calendarOptions: useAsyncData(getCalendars, { showError: true }),
crmOptions: useAsyncData(getCrmServices, { showError: true }),
features: useAsyncData(getFeaturesData, { showError: true }),
partners: useAsyncData(getPartners, { showError: true }),
admins: reactive(useAdminsList()),
});
const { close } = useDrawerModal({ onClose });
const { tierModel, featuresGroups } = useFeaturesManager();
const { requireSyncPeriod } = useRequireSyncPeriod();
const drawerAttrs = computed(() => ({
as: AppForm,
title: flags.teamCreated ? "Edit Organization" : "Setup Account",
headerButtons: [
{
type: "submit",
label: "Save",
variant: "primary",
"data-testid": "setup-trial-submit",
disabled: !unref(hasChanges),
},
],
contentAttrs: {
busy: Object.values(formData).some(({ loading }) => loading),
},
}));
function onClose() {
return modalDiscardGuard({
onSave: form.submitHandler,
hasChanges: unref(hasChanges),
});
}
async function onSubmit() {
const ownerChanged =
flags.ownerCreated && formState.value.owner_id !== props.data.owner_id;
if (ownerChanged) {
const confirmed = await promptModal(ChangeOwnerConfirmModal);
if (!confirmed) throw new SilentFormError("Owner change not confirmed");
}
const data = exportFormState();
// create or update the team
!flags.teamCreated
? await axios.post("/api/v1/settings/organizations", data)
: await axios.put(`/api/v1/kiosk/organizations/${props.data.id}`, data);
EventBus.$emit("team.updated");
// update form snapshot
updateSnapshot();
close();
}
function useFeaturesManager() {
const tierField = useField("tier_id", "required", {
initialValue: unref(formState).tier_id,
});
const tierModel = computed({
get() {
return unref(formState).tier_id;
},
set(tierId) {
setTier(tierId);
tierField.value.value = tierId;
},
});
const featuresGroups = computed(() => {
const { groups } = formData.features.data || {};
if (!groups) return [];
return [groups.TIER, groups["ADD_ON"]].filter(Boolean).flat();
});
function setTier(tierId) {
const selectedFeatures = new Set(unref(formState).features);
const { features, tiers } = formData.features.data;
// clear all tier features
features.byType.TIER.forEach(({ id }) => selectedFeatures.delete(id));
const tier = tiers.find((tier) => tier.id === tierId);
// select only selected tiers features
[...tier.inherits, tierId]
.map((tierId) => features.byTier[tierId] || [])
.flat()
.forEach((feature) => selectedFeatures.add(feature.id));
Object.assign(unref(formState), {
features: Array.from(selectedFeatures),
tier_id: tierId,
});
}
return { tierModel, setTier, featuresGroups };
}
function useRequireSyncPeriod() {
// Computed property to check if opportunity sync period is required
const requireSyncPeriod = computed(() => {
return !!formData.crmOptions.data?.find(
(item) => formState.value.crm === item.id,
)?.requireInitialSyncPeriod;
});
watch(requireSyncPeriod, (required) => {
formState.value.opportunity_sync_period = required
? formState.value.opportunity_sync_period ||
DEFAULT_OPPORTUNITY_SYNC_PERIOD
: null;
});
return { requireSyncPeriod };
}
function useAdminsList() {
return useAsyncData(async () => {
const data = await fetchUsersData(props.data.id);
return data.filter((user) => user.roles?.some((e) => e.name == "admin"));
});
}
</script>
<style lang="less" module>
.fieldLabel:has(~ * :disabled) {
opacity: 0.6;
}
.tearsGrid {
display: grid;
padding-top: 10px;
gap: 10px;
.sectionTitle {
margin-top: 30px;
display: flex;
justify-content: space-between;
}
}
.errorMessage {
color: var(--color-danger);
}
.docsRef {
font-size: 14px;
}
</style>
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v2\Api\ActivitiesApi;
use Pipedrive\versions\v2\Api\ActivityFieldsApi;
use Pipedrive\versions\v2\Api\DealFieldsApi;
use Pipedrive\versions\v2\Api\DealsApi;
use Pipedrive\versions\v2\Api\PersonFieldsApi;
use Pipedrive\versions\v2\Api\PersonsApi;
use Pipedrive\versions\v2\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$this->info('Test 2a: Get Deals');
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// v2 SDK might have different method names
// Try common v2 method names
try {
$result = $apiInstance->getDeals(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', true, "Retrieved deals in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder...
|
49810
|
NULL
|
NULL
|
NULL
|
|
49813
|
NULL
|
0
|
2026-05-18T06:59:49.373159+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087589373_m1.jpg...
|
PhpStorm
|
faVsco.js – ~/jiminny/app/front-end/src/components faVsco.js – ~/jiminny/app/front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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
2
Previous Highlighted Error
Next Highlighted Error
<template>
<AppDrawerModal v-bind="drawerAttrs" #default="{ $style: drawerStyle }">
<div :class="drawerStyle.formGrid">
<div :class="drawerStyle.sectionTitle">General</div>
<!-- Name -->
<AppFormField
field-label="Company name"
v-model="formState.name"
:required="true"
name="name"
rules="required"
data-testid="setup-trial-name"
/>
<!-- Owner Email -->
<AppFormField
v-if="!flags.ownerCreated"
type="email"
field-label="Owner Email"
v-model="formState.owner_email"
:required="true"
name="owner_email"
rules="required|email"
data-testid="setup-trial-owner-email"
/>
<AppFormField
v-else
field-label="Owner"
name="owner_id"
:required="true"
rules="required"
v-model="formState.owner_id"
:options="formData.admins.data || []"
:loading="formData.admins.loading"
type="select"
option-label="name"
track-by="id"
data-testid="setup-trial-owner-email"
/>
<!-- CRM -->
<AppFormField
v-model="formState.crm"
name="crm"
type="select"
field-label="CRM"
:required="true"
rules="required"
:options="formData.crmOptions.data || []"
track-by="id"
option-label="label"
:loading="formData.crmOptions.loading"
data-testid="setup-trial-crm"
:disabled="flags.ownerCreated"
/>
<!-- Partner (only shown to default-partner kiosk users in edit mode who have access to multiple partners) -->
<AppFormField
v-if="flags.teamCreated && formData.partners.data?.length > 1"
v-model="formState.partner_id"
name="partner_id"
type="select"
field-label="Partner"
:options="formData.partners.data || []"
track-by="id"
option-label="name"
:loading="formData.partners.loading"
data-testid="setup-trial-partner"
/>
<!-- Opportunity Sync Period -->
<AppFormField
:disabled="!requireSyncPeriod"
v-model="formState.opportunity_sync_period"
name="opportunity_sync_period"
type="select"
field-label="Import Opportunities Sync Period"
:required="requireSyncPeriod"
:rules="requireSyncPeriod ? 'required' : ''"
:options="syncPeriodOptions"
track-by="id"
option-label="label"
data-testid="setup-trial-sync-period"
/>
<!-- Calendar -->
<AppFormField
v-model="formState.calendar"
name="calendar"
type="radios"
ui="radios"
field-label="Calendar"
:required="true"
rules="required"
:options="formData.calendarOptions.data || []"
data-testid="setup-trial-calendar"
:disabled="flags.ownerCreated"
/>
<!-- Softphone -->
<div>
<div :class="[$style.fieldLabel, drawerStyle.fieldLabel]">
Softphone
</div>
<AppFormField
v-model="formState.features"
name="softphone"
type="checkbox"
:value="SOFTPHONE_FEATURE_ID"
:field-label="jiminnyVoiceLabel"
data-testid="setup-trial-softphone"
/>
</div>
<EditTeamAddressFields
v-if="softphoneEnabled"
:disabled="flags.billingDisabled"
/>
</div>
<div :class="$style.tearsGrid">
<div :class="$style.sectionTitle">
<div :class="drawerStyle.sectionTitle">Tiers & Add-ons</div>
<AppButton
icon="question"
label="Tiers explained"
mods="seamless link primary"
href="[URL_WITH_CREDENTIALS]
import useAppForm, {
SilentFormError,
} from "@/components/shared/AppFormElements/useAppForm";
import AppForm from "@/components/shared/AppFormElements/AppForm.vue";
import AppFormField from "@/components/shared/AppFormElements/AppFormField.vue";
import useAsyncData from "@/composables/useAsyncData";
import EditTeamAddressFields from "./EditTeamAddressFields.vue";
import AppDrawerModal from "@/components/shared/modals/AppDrawerModal.vue";
import { useDrawerModal } from "@/composables/useDrawerModal";
import { promptModal } from "jenesius-vue-modal";
import ChangeOwnerConfirmModal from "@/components/Settings/OrgSettings/Members/ChangeOwnerConfirmModal.vue";
import EventBus from "@/utils/event-bus";
import { getFeaturesData } from "./features";
import FeaturesGroup from "./FeaturesGroup.vue";
import FeaturesList from "./FeaturesList.vue";
import { ErrorMessage, useField } from "vee-validate";
import AppButton from "@/components/shared/Buttons/AppButton.vue";
import { useBrandedI18n } from "@/composables/useBrandedI18n";
// Define props
const props = defineProps({
data: {
type: Object,
required: true,
},
teamId: String,
});
const { tb } = useBrandedI18n();
// Branded i18n computed ref
const jiminnyVoiceLabel = tb("kiosk.edit-team.jiminny-voice--whitelabel");
const flags = reactive({
teamCreated: computed(() => !!props.data.id),
ownerCreated: computed(() => !!props.data.owner_id),
billingDisabled: computed(
() =>
!!props.data.id && props.data?.features?.includes(SOFTPHONE_FEATURE_ID),
),
});
// Setup form
const form = useAppForm({
onSubmit,
toastSuccess: flags.teamCreated
? "Account updated successfully!"
: "Account created successfully!",
});
// Setup form state with initial values
const {
formState,
hasChanges,
updateSnapshot,
exportFormState,
softphoneEnabled,
} = useEditTeamForm(props.data);
// Load required data
const formData = reactive({
calendarOptions: useAsyncData(getCalendars, { showError: true }),
crmOptions: useAsyncData(getCrmServices, { showError: true }),
features: useAsyncData(getFeaturesData, { showError: true }),
partners: useAsyncData(getPartners, { showError: true }),
admins: reactive(useAdminsList()),
});
const { close } = useDrawerModal({ onClose });
const { tierModel, featuresGroups } = useFeaturesManager();
const { requireSyncPeriod } = useRequireSyncPeriod();
const drawerAttrs = computed(() => ({
as: AppForm,
title: flags.teamCreated ? "Edit Organization" : "Setup Account",
headerButtons: [
{
type: "submit",
label: "Save",
variant: "primary",
"data-testid": "setup-trial-submit",
disabled: !unref(hasChanges),
},
],
contentAttrs: {
busy: Object.values(formData).some(({ loading }) => loading),
},
}));
function onClose() {
return modalDiscardGuard({
onSave: form.submitHandler,
hasChanges: unref(hasChanges),
});
}
async function onSubmit() {
const ownerChanged =
flags.ownerCreated && formState.value.owner_id !== props.data.owner_id;
if (ownerChanged) {
const confirmed = await promptModal(ChangeOwnerConfirmModal);
if (!confirmed) throw new SilentFormError("Owner change not confirmed");
}
const data = exportFormState();
// create or update the team
!flags.teamCreated
? await axios.post("/api/v1/settings/organizations", data)
: await axios.put(`/api/v1/kiosk/organizations/${props.data.id}`, data);
EventBus.$emit("team.updated");
// update form snapshot
updateSnapshot();
close();
}
function useFeaturesManager() {
const tierField = useField("tier_id", "required", {
initialValue: unref(formState).tier_id,
});
const tierModel = computed({
get() {
return unref(formState).tier_id;
},
set(tierId) {
setTier(tierId);
tierField.value.value = tierId;
},
});
const featuresGroups = computed(() => {
const { groups } = formData.features.data || {};
if (!groups) return [];
return [groups.TIER, groups["ADD_ON"]].filter(Boolean).flat();
});
function setTier(tierId) {
const selectedFeatures = new Set(unref(formState).features);
const { features, tiers } = formData.features.data;
// clear all tier features
features.byType.TIER.forEach(({ id }) => selectedFeatures.delete(id));
const tier = tiers.find((tier) => tier.id === tierId);
// select only selected tiers features
[...tier.inherits, tierId]
.map((tierId) => features.byTier[tierId] || [])
.flat()
.forEach((feature) => selectedFeatures.add(feature.id));
Object.assign(unref(formState), {
features: Array.from(selectedFeatures),
tier_id: tierId,
});
}
return { tierModel, setTier, featuresGroups };
}
function useRequireSyncPeriod() {
// Computed property to check if opportunity sync period is required
const requireSyncPeriod = computed(() => {
return !!formData.crmOptions.data?.find(
(item) => formState.value.crm === item.id,
)?.requireInitialSyncPeriod;
});
watch(requireSyncPeriod, (required) => {
formState.value.opportunity_sync_period = required
? formState.value.opportunity_sync_period ||
DEFAULT_OPPORTUNITY_SYNC_PERIOD
: null;
});
return { requireSyncPeriod };
}
function useAdminsList() {
return useAsyncData(async () => {
const data = await fetchUsersData(props.data.id);
return data.filter((user) => user.roles?.some((e) => e.name == "admin"));
});
}
</script>
<style lang="less" module>
.fieldLabel:has(~ * :disabled) {
opacity: 0.6;
}
.tearsGrid {
display: grid;
padding-top: 10px;
gap: 10px;
.sectionTitle {
margin-top: 30px;
display: flex;
justify-content: space-between;
}
}
.errorMessage {
color: var(--color-danger);
}
.docsRef {
font-size: 14px;
}
</style>
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v2\Api\ActivitiesApi;
use Pipedrive\versions\v2\Api\ActivityFieldsApi;
use Pipedrive\versions\v2\Api\DealFieldsApi;
use Pipedrive\versions\v2\Api\DealsApi;
use Pipedrive\versions\v2\Api\PersonFieldsApi;
use Pipedrive\versions\v2\Api\PersonsApi;
use Pipedrive\versions\v2\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$this->info('Test 2a: Get Deals');
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// v2 SDK might have different method names
// Try common v2 method names
try {
$result = $apiInstance->getDeals(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', true, "Retrieved deals in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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":"AXStaticText","text":"2","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":"<template>\n <AppDrawerModal v-bind=\"drawerAttrs\" #default=\"{ $style: drawerStyle }\">\n <div :class=\"drawerStyle.formGrid\">\n <div :class=\"drawerStyle.sectionTitle\">General</div>\n <!-- Name -->\n <AppFormField\n field-label=\"Company name\"\n v-model=\"formState.name\"\n :required=\"true\"\n name=\"name\"\n rules=\"required\"\n data-testid=\"setup-trial-name\"\n />\n\n <!-- Owner Email -->\n <AppFormField\n v-if=\"!flags.ownerCreated\"\n type=\"email\"\n field-label=\"Owner Email\"\n v-model=\"formState.owner_email\"\n :required=\"true\"\n name=\"owner_email\"\n rules=\"required|email\"\n data-testid=\"setup-trial-owner-email\"\n />\n <AppFormField\n v-else\n field-label=\"Owner\"\n name=\"owner_id\"\n :required=\"true\"\n rules=\"required\"\n v-model=\"formState.owner_id\"\n :options=\"formData.admins.data || []\"\n :loading=\"formData.admins.loading\"\n type=\"select\"\n option-label=\"name\"\n track-by=\"id\"\n data-testid=\"setup-trial-owner-email\"\n />\n\n <!-- CRM -->\n <AppFormField\n v-model=\"formState.crm\"\n name=\"crm\"\n type=\"select\"\n field-label=\"CRM\"\n :required=\"true\"\n rules=\"required\"\n :options=\"formData.crmOptions.data || []\"\n track-by=\"id\"\n option-label=\"label\"\n :loading=\"formData.crmOptions.loading\"\n data-testid=\"setup-trial-crm\"\n :disabled=\"flags.ownerCreated\"\n />\n\n <!-- Partner (only shown to default-partner kiosk users in edit mode who have access to multiple partners) -->\n <AppFormField\n v-if=\"flags.teamCreated && formData.partners.data?.length > 1\"\n v-model=\"formState.partner_id\"\n name=\"partner_id\"\n type=\"select\"\n field-label=\"Partner\"\n :options=\"formData.partners.data || []\"\n track-by=\"id\"\n option-label=\"name\"\n :loading=\"formData.partners.loading\"\n data-testid=\"setup-trial-partner\"\n />\n\n <!-- Opportunity Sync Period -->\n <AppFormField\n :disabled=\"!requireSyncPeriod\"\n v-model=\"formState.opportunity_sync_period\"\n name=\"opportunity_sync_period\"\n type=\"select\"\n field-label=\"Import Opportunities Sync Period\"\n :required=\"requireSyncPeriod\"\n :rules=\"requireSyncPeriod ? 'required' : ''\"\n :options=\"syncPeriodOptions\"\n track-by=\"id\"\n option-label=\"label\"\n data-testid=\"setup-trial-sync-period\"\n />\n\n <!-- Calendar -->\n <AppFormField\n v-model=\"formState.calendar\"\n name=\"calendar\"\n type=\"radios\"\n ui=\"radios\"\n field-label=\"Calendar\"\n :required=\"true\"\n rules=\"required\"\n :options=\"formData.calendarOptions.data || []\"\n data-testid=\"setup-trial-calendar\"\n :disabled=\"flags.ownerCreated\"\n />\n\n <!-- Softphone -->\n <div>\n <div :class=\"[$style.fieldLabel, drawerStyle.fieldLabel]\">\n Softphone\n </div>\n <AppFormField\n v-model=\"formState.features\"\n name=\"softphone\"\n type=\"checkbox\"\n :value=\"SOFTPHONE_FEATURE_ID\"\n :field-label=\"jiminnyVoiceLabel\"\n data-testid=\"setup-trial-softphone\"\n />\n </div>\n\n <EditTeamAddressFields\n v-if=\"softphoneEnabled\"\n :disabled=\"flags.billingDisabled\"\n />\n\n </div>\n <div :class=\"$style.tearsGrid\">\n <div :class=\"$style.sectionTitle\">\n <div :class=\"drawerStyle.sectionTitle\">Tiers & Add-ons</div>\n <AppButton\n icon=\"question\"\n label=\"Tiers explained\"\n mods=\"seamless link primary\"\n href=\"https://jiminny.atlassian.net/wiki/external/OGRhNWI0NzJjZTc0NDg1YTg5MTU4NGYwZWU3NTc2OGM\"\n :class=\"$style.docsRef\"\n />\n </div>\n <ErrorMessage name=\"tier_id\">\n <div :class=\"$style.errorMessage\">Selecting tier is required</div>\n </ErrorMessage>\n <FeaturesGroup\n v-for=\"group in featuresGroups\"\n :key=\"group.tier?.id || group.type\"\n v-bind=\"{ group, tiers: formData.features.data.tiers }\"\n v-model:tier=\"tierModel\"\n v-model:features=\"formState.features\"\n />\n <template\n v-if=\"\n flags.teamCreated &&\n formData.features.data?.features.byType.DEV?.length\n \"\n >\n <div :class=\"[$style.sectionTitle, drawerStyle.sectionTitle]\">\n Technical Settings\n </div>\n <FeaturesList\n v-model=\"formState.features\"\n :features=\"formData.features.data.features.byType.DEV\"\n />\n </template>\n </div>\n </AppDrawerModal>\n</template>\n<script>\nconst SOFTPHONE_FEATURE_ID = \"DIALER\";\n\n// Options for opportunity sync period\nconst syncPeriodOptions = [\n { id: \"3m\", label: \"3 Months\" },\n { id: \"6m\", label: \"6 Months\" },\n { id: \"12m\", label: \"12 Months\" },\n];\n\nconst DEFAULT_OPPORTUNITY_SYNC_PERIOD = syncPeriodOptions[0].id;\n\nexport const useEditTeamForm = toSelfProvidingHook((data) => {\n const formState = ref({\n features: [],\n ...data,\n });\n\n const formStateSnapshot = ref();\n\n updateSnapshot();\n\n const hasChanges = computed(\n () => !isEqual(formState.value, formStateSnapshot.value),\n );\n\n const softphoneEnabled = computed(() =>\n unref(formState).features?.includes(SOFTPHONE_FEATURE_ID),\n );\n\n function exportFormState() {\n const excluded = [\"softphone\"];\n\n if (!unref(softphoneEnabled)) {\n excluded.push(\"address\", \"city\", \"state\", \"zip\", \"country\");\n }\n\n return omit(formState.value, excluded);\n }\n\n function updateSnapshot() {\n formStateSnapshot.value = cloneDeep(formState.value);\n }\n\n return {\n formState,\n updateSnapshot,\n hasChanges,\n exportFormState,\n softphoneEnabled,\n };\n});\n\n// Data loading functions\nasync function getCalendars() {\n const { error, data } = await tryCatch(axios.get(\"/api/v1/calendars\"));\n\n if (!error) return data.data.map(({ id, label }) => ({ value: id, label }));\n\n console.error(error);\n throw new Error(\"Error loading calendars\");\n}\n\nasync function getCrmServices() {\n const { error, data } = await tryCatch(axios.get(\"/api/v1/crm-services\"));\n if (!error) return Object.values(data.data);\n\n console.error(error);\n throw new Error(\"Error loading CRM services\");\n}\n\nasync function getPartners() {\n const { error, data } = await tryCatch(\n axios.get(\"/api/v1/kiosk/partners\"),\n );\n if (!error) return data.data.data;\n\n console.error(error);\n throw new Error(\"Error loading partners\");\n}\n\nasync function fetchUsersData(teamId) {\n const { data, status } = await axios.get(\n `/api/v1/kiosk/organizations/${teamId}/users`,\n );\n\n if (status === 200) {\n return data;\n } else {\n throw new Error(\"Error in fetching users data\");\n }\n}\n</script>\n<script setup>\nimport { computed, ref, reactive, watch, unref } from \"vue\";\nimport axios from \"axios\";\nimport { cloneDeep, isEqual, omit } from \"lodash-es\";\nimport { modalDiscardGuard, toSelfProvidingHook, tryCatch } from \"@/utils\";\nimport useAppForm, {\n SilentFormError,\n} from \"@/components/shared/AppFormElements/useAppForm\";\nimport AppForm from \"@/components/shared/AppFormElements/AppForm.vue\";\nimport AppFormField from \"@/components/shared/AppFormElements/AppFormField.vue\";\nimport useAsyncData from \"@/composables/useAsyncData\";\nimport EditTeamAddressFields from \"./EditTeamAddressFields.vue\";\nimport AppDrawerModal from \"@/components/shared/modals/AppDrawerModal.vue\";\nimport { useDrawerModal } from \"@/composables/useDrawerModal\";\nimport { promptModal } from \"jenesius-vue-modal\";\nimport ChangeOwnerConfirmModal from \"@/components/Settings/OrgSettings/Members/ChangeOwnerConfirmModal.vue\";\nimport EventBus from \"@/utils/event-bus\";\nimport { getFeaturesData } from \"./features\";\nimport FeaturesGroup from \"./FeaturesGroup.vue\";\nimport FeaturesList from \"./FeaturesList.vue\";\nimport { ErrorMessage, useField } from \"vee-validate\";\nimport AppButton from \"@/components/shared/Buttons/AppButton.vue\";\nimport { useBrandedI18n } from \"@/composables/useBrandedI18n\";\n\n// Define props\nconst props = defineProps({\n data: {\n type: Object,\n required: true,\n },\n teamId: String,\n});\n\nconst { tb } = useBrandedI18n();\n\n// Branded i18n computed ref\nconst jiminnyVoiceLabel = tb(\"kiosk.edit-team.jiminny-voice--whitelabel\");\n\nconst flags = reactive({\n teamCreated: computed(() => !!props.data.id),\n ownerCreated: computed(() => !!props.data.owner_id),\n billingDisabled: computed(\n () =>\n !!props.data.id && props.data?.features?.includes(SOFTPHONE_FEATURE_ID),\n ),\n});\n\n// Setup form\nconst form = useAppForm({\n onSubmit,\n toastSuccess: flags.teamCreated\n ? \"Account updated successfully!\"\n : \"Account created successfully!\",\n});\n\n// Setup form state with initial values\nconst {\n formState,\n hasChanges,\n updateSnapshot,\n exportFormState,\n softphoneEnabled,\n} = useEditTeamForm(props.data);\n\n// Load required data\nconst formData = reactive({\n calendarOptions: useAsyncData(getCalendars, { showError: true }),\n crmOptions: useAsyncData(getCrmServices, { showError: true }),\n features: useAsyncData(getFeaturesData, { showError: true }),\n partners: useAsyncData(getPartners, { showError: true }),\n admins: reactive(useAdminsList()),\n});\n\nconst { close } = useDrawerModal({ onClose });\n\nconst { tierModel, featuresGroups } = useFeaturesManager();\n\nconst { requireSyncPeriod } = useRequireSyncPeriod();\n\nconst drawerAttrs = computed(() => ({\n as: AppForm,\n title: flags.teamCreated ? \"Edit Organization\" : \"Setup Account\",\n headerButtons: [\n {\n type: \"submit\",\n label: \"Save\",\n variant: \"primary\",\n \"data-testid\": \"setup-trial-submit\",\n disabled: !unref(hasChanges),\n },\n ],\n contentAttrs: {\n busy: Object.values(formData).some(({ loading }) => loading),\n },\n}));\n\nfunction onClose() {\n return modalDiscardGuard({\n onSave: form.submitHandler,\n hasChanges: unref(hasChanges),\n });\n}\n\nasync function onSubmit() {\n const ownerChanged =\n flags.ownerCreated && formState.value.owner_id !== props.data.owner_id;\n\n if (ownerChanged) {\n const confirmed = await promptModal(ChangeOwnerConfirmModal);\n if (!confirmed) throw new SilentFormError(\"Owner change not confirmed\");\n }\n\n const data = exportFormState();\n\n // create or update the team\n !flags.teamCreated\n ? await axios.post(\"/api/v1/settings/organizations\", data)\n : await axios.put(`/api/v1/kiosk/organizations/${props.data.id}`, data);\n\n EventBus.$emit(\"team.updated\");\n\n // update form snapshot\n updateSnapshot();\n close();\n}\n\nfunction useFeaturesManager() {\n const tierField = useField(\"tier_id\", \"required\", {\n initialValue: unref(formState).tier_id,\n });\n\n const tierModel = computed({\n get() {\n return unref(formState).tier_id;\n },\n set(tierId) {\n setTier(tierId);\n tierField.value.value = tierId;\n },\n });\n\n const featuresGroups = computed(() => {\n const { groups } = formData.features.data || {};\n\n if (!groups) return [];\n\n return [groups.TIER, groups[\"ADD_ON\"]].filter(Boolean).flat();\n });\n\n function setTier(tierId) {\n const selectedFeatures = new Set(unref(formState).features);\n const { features, tiers } = formData.features.data;\n\n // clear all tier features\n features.byType.TIER.forEach(({ id }) => selectedFeatures.delete(id));\n\n const tier = tiers.find((tier) => tier.id === tierId);\n\n // select only selected tiers features\n [...tier.inherits, tierId]\n .map((tierId) => features.byTier[tierId] || [])\n .flat()\n .forEach((feature) => selectedFeatures.add(feature.id));\n\n Object.assign(unref(formState), {\n features: Array.from(selectedFeatures),\n tier_id: tierId,\n });\n }\n\n return { tierModel, setTier, featuresGroups };\n}\n\nfunction useRequireSyncPeriod() {\n // Computed property to check if opportunity sync period is required\n const requireSyncPeriod = computed(() => {\n return !!formData.crmOptions.data?.find(\n (item) => formState.value.crm === item.id,\n )?.requireInitialSyncPeriod;\n });\n\n watch(requireSyncPeriod, (required) => {\n formState.value.opportunity_sync_period = required\n ? formState.value.opportunity_sync_period ||\n DEFAULT_OPPORTUNITY_SYNC_PERIOD\n : null;\n });\n\n return { requireSyncPeriod };\n}\n\nfunction useAdminsList() {\n return useAsyncData(async () => {\n const data = await fetchUsersData(props.data.id);\n\n return data.filter((user) => user.roles?.some((e) => e.name == \"admin\"));\n });\n}\n</script>\n\n<style lang=\"less\" module>\n.fieldLabel:has(~ * :disabled) {\n opacity: 0.6;\n}\n.tearsGrid {\n display: grid;\n padding-top: 10px;\n gap: 10px;\n .sectionTitle {\n margin-top: 30px;\n display: flex;\n justify-content: space-between;\n }\n}\n.errorMessage {\n color: var(--color-danger);\n}\n.docsRef {\n font-size: 14px;\n}\n</style>","depth":4,"on_screen":true,"value":"<template>\n <AppDrawerModal v-bind=\"drawerAttrs\" #default=\"{ $style: drawerStyle }\">\n <div :class=\"drawerStyle.formGrid\">\n <div :class=\"drawerStyle.sectionTitle\">General</div>\n <!-- Name -->\n <AppFormField\n field-label=\"Company name\"\n v-model=\"formState.name\"\n :required=\"true\"\n name=\"name\"\n rules=\"required\"\n data-testid=\"setup-trial-name\"\n />\n\n <!-- Owner Email -->\n <AppFormField\n v-if=\"!flags.ownerCreated\"\n type=\"email\"\n field-label=\"Owner Email\"\n v-model=\"formState.owner_email\"\n :required=\"true\"\n name=\"owner_email\"\n rules=\"required|email\"\n data-testid=\"setup-trial-owner-email\"\n />\n <AppFormField\n v-else\n field-label=\"Owner\"\n name=\"owner_id\"\n :required=\"true\"\n rules=\"required\"\n v-model=\"formState.owner_id\"\n :options=\"formData.admins.data || []\"\n :loading=\"formData.admins.loading\"\n type=\"select\"\n option-label=\"name\"\n track-by=\"id\"\n data-testid=\"setup-trial-owner-email\"\n />\n\n <!-- CRM -->\n <AppFormField\n v-model=\"formState.crm\"\n name=\"crm\"\n type=\"select\"\n field-label=\"CRM\"\n :required=\"true\"\n rules=\"required\"\n :options=\"formData.crmOptions.data || []\"\n track-by=\"id\"\n option-label=\"label\"\n :loading=\"formData.crmOptions.loading\"\n data-testid=\"setup-trial-crm\"\n :disabled=\"flags.ownerCreated\"\n />\n\n <!-- Partner (only shown to default-partner kiosk users in edit mode who have access to multiple partners) -->\n <AppFormField\n v-if=\"flags.teamCreated && formData.partners.data?.length > 1\"\n v-model=\"formState.partner_id\"\n name=\"partner_id\"\n type=\"select\"\n field-label=\"Partner\"\n :options=\"formData.partners.data || []\"\n track-by=\"id\"\n option-label=\"name\"\n :loading=\"formData.partners.loading\"\n data-testid=\"setup-trial-partner\"\n />\n\n <!-- Opportunity Sync Period -->\n <AppFormField\n :disabled=\"!requireSyncPeriod\"\n v-model=\"formState.opportunity_sync_period\"\n name=\"opportunity_sync_period\"\n type=\"select\"\n field-label=\"Import Opportunities Sync Period\"\n :required=\"requireSyncPeriod\"\n :rules=\"requireSyncPeriod ? 'required' : ''\"\n :options=\"syncPeriodOptions\"\n track-by=\"id\"\n option-label=\"label\"\n data-testid=\"setup-trial-sync-period\"\n />\n\n <!-- Calendar -->\n <AppFormField\n v-model=\"formState.calendar\"\n name=\"calendar\"\n type=\"radios\"\n ui=\"radios\"\n field-label=\"Calendar\"\n :required=\"true\"\n rules=\"required\"\n :options=\"formData.calendarOptions.data || []\"\n data-testid=\"setup-trial-calendar\"\n :disabled=\"flags.ownerCreated\"\n />\n\n <!-- Softphone -->\n <div>\n <div :class=\"[$style.fieldLabel, drawerStyle.fieldLabel]\">\n Softphone\n </div>\n <AppFormField\n v-model=\"formState.features\"\n name=\"softphone\"\n type=\"checkbox\"\n :value=\"SOFTPHONE_FEATURE_ID\"\n :field-label=\"jiminnyVoiceLabel\"\n data-testid=\"setup-trial-softphone\"\n />\n </div>\n\n <EditTeamAddressFields\n v-if=\"softphoneEnabled\"\n :disabled=\"flags.billingDisabled\"\n />\n\n </div>\n <div :class=\"$style.tearsGrid\">\n <div :class=\"$style.sectionTitle\">\n <div :class=\"drawerStyle.sectionTitle\">Tiers & Add-ons</div>\n <AppButton\n icon=\"question\"\n label=\"Tiers explained\"\n mods=\"seamless link primary\"\n href=\"https://jiminny.atlassian.net/wiki/external/OGRhNWI0NzJjZTc0NDg1YTg5MTU4NGYwZWU3NTc2OGM\"\n :class=\"$style.docsRef\"\n />\n </div>\n <ErrorMessage name=\"tier_id\">\n <div :class=\"$style.errorMessage\">Selecting tier is required</div>\n </ErrorMessage>\n <FeaturesGroup\n v-for=\"group in featuresGroups\"\n :key=\"group.tier?.id || group.type\"\n v-bind=\"{ group, tiers: formData.features.data.tiers }\"\n v-model:tier=\"tierModel\"\n v-model:features=\"formState.features\"\n />\n <template\n v-if=\"\n flags.teamCreated &&\n formData.features.data?.features.byType.DEV?.length\n \"\n >\n <div :class=\"[$style.sectionTitle, drawerStyle.sectionTitle]\">\n Technical Settings\n </div>\n <FeaturesList\n v-model=\"formState.features\"\n :features=\"formData.features.data.features.byType.DEV\"\n />\n </template>\n </div>\n </AppDrawerModal>\n</template>\n<script>\nconst SOFTPHONE_FEATURE_ID = \"DIALER\";\n\n// Options for opportunity sync period\nconst syncPeriodOptions = [\n { id: \"3m\", label: \"3 Months\" },\n { id: \"6m\", label: \"6 Months\" },\n { id: \"12m\", label: \"12 Months\" },\n];\n\nconst DEFAULT_OPPORTUNITY_SYNC_PERIOD = syncPeriodOptions[0].id;\n\nexport const useEditTeamForm = toSelfProvidingHook((data) => {\n const formState = ref({\n features: [],\n ...data,\n });\n\n const formStateSnapshot = ref();\n\n updateSnapshot();\n\n const hasChanges = computed(\n () => !isEqual(formState.value, formStateSnapshot.value),\n );\n\n const softphoneEnabled = computed(() =>\n unref(formState).features?.includes(SOFTPHONE_FEATURE_ID),\n );\n\n function exportFormState() {\n const excluded = [\"softphone\"];\n\n if (!unref(softphoneEnabled)) {\n excluded.push(\"address\", \"city\", \"state\", \"zip\", \"country\");\n }\n\n return omit(formState.value, excluded);\n }\n\n function updateSnapshot() {\n formStateSnapshot.value = cloneDeep(formState.value);\n }\n\n return {\n formState,\n updateSnapshot,\n hasChanges,\n exportFormState,\n softphoneEnabled,\n };\n});\n\n// Data loading functions\nasync function getCalendars() {\n const { error, data } = await tryCatch(axios.get(\"/api/v1/calendars\"));\n\n if (!error) return data.data.map(({ id, label }) => ({ value: id, label }));\n\n console.error(error);\n throw new Error(\"Error loading calendars\");\n}\n\nasync function getCrmServices() {\n const { error, data } = await tryCatch(axios.get(\"/api/v1/crm-services\"));\n if (!error) return Object.values(data.data);\n\n console.error(error);\n throw new Error(\"Error loading CRM services\");\n}\n\nasync function getPartners() {\n const { error, data } = await tryCatch(\n axios.get(\"/api/v1/kiosk/partners\"),\n );\n if (!error) return data.data.data;\n\n console.error(error);\n throw new Error(\"Error loading partners\");\n}\n\nasync function fetchUsersData(teamId) {\n const { data, status } = await axios.get(\n `/api/v1/kiosk/organizations/${teamId}/users`,\n );\n\n if (status === 200) {\n return data;\n } else {\n throw new Error(\"Error in fetching users data\");\n }\n}\n</script>\n<script setup>\nimport { computed, ref, reactive, watch, unref } from \"vue\";\nimport axios from \"axios\";\nimport { cloneDeep, isEqual, omit } from \"lodash-es\";\nimport { modalDiscardGuard, toSelfProvidingHook, tryCatch } from \"@/utils\";\nimport useAppForm, {\n SilentFormError,\n} from \"@/components/shared/AppFormElements/useAppForm\";\nimport AppForm from \"@/components/shared/AppFormElements/AppForm.vue\";\nimport AppFormField from \"@/components/shared/AppFormElements/AppFormField.vue\";\nimport useAsyncData from \"@/composables/useAsyncData\";\nimport EditTeamAddressFields from \"./EditTeamAddressFields.vue\";\nimport AppDrawerModal from \"@/components/shared/modals/AppDrawerModal.vue\";\nimport { useDrawerModal } from \"@/composables/useDrawerModal\";\nimport { promptModal } from \"jenesius-vue-modal\";\nimport ChangeOwnerConfirmModal from \"@/components/Settings/OrgSettings/Members/ChangeOwnerConfirmModal.vue\";\nimport EventBus from \"@/utils/event-bus\";\nimport { getFeaturesData } from \"./features\";\nimport FeaturesGroup from \"./FeaturesGroup.vue\";\nimport FeaturesList from \"./FeaturesList.vue\";\nimport { ErrorMessage, useField } from \"vee-validate\";\nimport AppButton from \"@/components/shared/Buttons/AppButton.vue\";\nimport { useBrandedI18n } from \"@/composables/useBrandedI18n\";\n\n// Define props\nconst props = defineProps({\n data: {\n type: Object,\n required: true,\n },\n teamId: String,\n});\n\nconst { tb } = useBrandedI18n();\n\n// Branded i18n computed ref\nconst jiminnyVoiceLabel = tb(\"kiosk.edit-team.jiminny-voice--whitelabel\");\n\nconst flags = reactive({\n teamCreated: computed(() => !!props.data.id),\n ownerCreated: computed(() => !!props.data.owner_id),\n billingDisabled: computed(\n () =>\n !!props.data.id && props.data?.features?.includes(SOFTPHONE_FEATURE_ID),\n ),\n});\n\n// Setup form\nconst form = useAppForm({\n onSubmit,\n toastSuccess: flags.teamCreated\n ? \"Account updated successfully!\"\n : \"Account created successfully!\",\n});\n\n// Setup form state with initial values\nconst {\n formState,\n hasChanges,\n updateSnapshot,\n exportFormState,\n softphoneEnabled,\n} = useEditTeamForm(props.data);\n\n// Load required data\nconst formData = reactive({\n calendarOptions: useAsyncData(getCalendars, { showError: true }),\n crmOptions: useAsyncData(getCrmServices, { showError: true }),\n features: useAsyncData(getFeaturesData, { showError: true }),\n partners: useAsyncData(getPartners, { showError: true }),\n admins: reactive(useAdminsList()),\n});\n\nconst { close } = useDrawerModal({ onClose });\n\nconst { tierModel, featuresGroups } = useFeaturesManager();\n\nconst { requireSyncPeriod } = useRequireSyncPeriod();\n\nconst drawerAttrs = computed(() => ({\n as: AppForm,\n title: flags.teamCreated ? \"Edit Organization\" : \"Setup Account\",\n headerButtons: [\n {\n type: \"submit\",\n label: \"Save\",\n variant: \"primary\",\n \"data-testid\": \"setup-trial-submit\",\n disabled: !unref(hasChanges),\n },\n ],\n contentAttrs: {\n busy: Object.values(formData).some(({ loading }) => loading),\n },\n}));\n\nfunction onClose() {\n return modalDiscardGuard({\n onSave: form.submitHandler,\n hasChanges: unref(hasChanges),\n });\n}\n\nasync function onSubmit() {\n const ownerChanged =\n flags.ownerCreated && formState.value.owner_id !== props.data.owner_id;\n\n if (ownerChanged) {\n const confirmed = await promptModal(ChangeOwnerConfirmModal);\n if (!confirmed) throw new SilentFormError(\"Owner change not confirmed\");\n }\n\n const data = exportFormState();\n\n // create or update the team\n !flags.teamCreated\n ? await axios.post(\"/api/v1/settings/organizations\", data)\n : await axios.put(`/api/v1/kiosk/organizations/${props.data.id}`, data);\n\n EventBus.$emit(\"team.updated\");\n\n // update form snapshot\n updateSnapshot();\n close();\n}\n\nfunction useFeaturesManager() {\n const tierField = useField(\"tier_id\", \"required\", {\n initialValue: unref(formState).tier_id,\n });\n\n const tierModel = computed({\n get() {\n return unref(formState).tier_id;\n },\n set(tierId) {\n setTier(tierId);\n tierField.value.value = tierId;\n },\n });\n\n const featuresGroups = computed(() => {\n const { groups } = formData.features.data || {};\n\n if (!groups) return [];\n\n return [groups.TIER, groups[\"ADD_ON\"]].filter(Boolean).flat();\n });\n\n function setTier(tierId) {\n const selectedFeatures = new Set(unref(formState).features);\n const { features, tiers } = formData.features.data;\n\n // clear all tier features\n features.byType.TIER.forEach(({ id }) => selectedFeatures.delete(id));\n\n const tier = tiers.find((tier) => tier.id === tierId);\n\n // select only selected tiers features\n [...tier.inherits, tierId]\n .map((tierId) => features.byTier[tierId] || [])\n .flat()\n .forEach((feature) => selectedFeatures.add(feature.id));\n\n Object.assign(unref(formState), {\n features: Array.from(selectedFeatures),\n tier_id: tierId,\n });\n }\n\n return { tierModel, setTier, featuresGroups };\n}\n\nfunction useRequireSyncPeriod() {\n // Computed property to check if opportunity sync period is required\n const requireSyncPeriod = computed(() => {\n return !!formData.crmOptions.data?.find(\n (item) => formState.value.crm === item.id,\n )?.requireInitialSyncPeriod;\n });\n\n watch(requireSyncPeriod, (required) => {\n formState.value.opportunity_sync_period = required\n ? formState.value.opportunity_sync_period ||\n DEFAULT_OPPORTUNITY_SYNC_PERIOD\n : null;\n });\n\n return { requireSyncPeriod };\n}\n\nfunction useAdminsList() {\n return useAsyncData(async () => {\n const data = await fetchUsersData(props.data.id);\n\n return data.filter((user) => user.roles?.some((e) => e.name == \"admin\"));\n });\n}\n</script>\n\n<style lang=\"less\" module>\n.fieldLabel:has(~ * :disabled) {\n opacity: 0.6;\n}\n.tearsGrid {\n display: grid;\n padding-top: 10px;\n gap: 10px;\n .sectionTitle {\n margin-top: 30px;\n display: flex;\n justify-content: space-between;\n }\n}\n.errorMessage {\n color: var(--color-danger);\n}\n.docsRef {\n font-size: 14px;\n}\n</style>","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,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.02013889,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"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\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v2\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v2\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v2\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $this->info('Test 2a: Get Deals');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // v2 SDK might have different method names\n // Try common v2 method names\n try {\n $result = $apiInstance->getDeals(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', true, \"Retrieved deals in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method\n $result = $apiInstance->getDealsSummary();\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v2\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v2\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\DealsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v2\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v2\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $this->info('Test 2a: Get Deals');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // v2 SDK might have different method names\n // Try common v2 method names\n try {\n $result = $apiInstance->getDeals(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', true, \"Retrieved deals in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method\n $result = $apiInstance->getDealsSummary();\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllPersons(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"Retrieved persons in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // v2 SDK might have different method names\n try {\n $result = $apiInstance->getActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n // Try alternative method names\n try {\n $result = $apiInstance->getAllActivities(['limit' => 10]);\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"Retrieved activities in {$elapsed}ms\", $elapsed);\n } catch (Exception $e2) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, \"Method not found: {$e->getMessage()}\", $elapsed);\n }\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\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}]...
|
8824526876037876371
|
25694249123465860
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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
2
Previous Highlighted Error
Next Highlighted Error
<template>
<AppDrawerModal v-bind="drawerAttrs" #default="{ $style: drawerStyle }">
<div :class="drawerStyle.formGrid">
<div :class="drawerStyle.sectionTitle">General</div>
<!-- Name -->
<AppFormField
field-label="Company name"
v-model="formState.name"
:required="true"
name="name"
rules="required"
data-testid="setup-trial-name"
/>
<!-- Owner Email -->
<AppFormField
v-if="!flags.ownerCreated"
type="email"
field-label="Owner Email"
v-model="formState.owner_email"
:required="true"
name="owner_email"
rules="required|email"
data-testid="setup-trial-owner-email"
/>
<AppFormField
v-else
field-label="Owner"
name="owner_id"
:required="true"
rules="required"
v-model="formState.owner_id"
:options="formData.admins.data || []"
:loading="formData.admins.loading"
type="select"
option-label="name"
track-by="id"
data-testid="setup-trial-owner-email"
/>
<!-- CRM -->
<AppFormField
v-model="formState.crm"
name="crm"
type="select"
field-label="CRM"
:required="true"
rules="required"
:options="formData.crmOptions.data || []"
track-by="id"
option-label="label"
:loading="formData.crmOptions.loading"
data-testid="setup-trial-crm"
:disabled="flags.ownerCreated"
/>
<!-- Partner (only shown to default-partner kiosk users in edit mode who have access to multiple partners) -->
<AppFormField
v-if="flags.teamCreated && formData.partners.data?.length > 1"
v-model="formState.partner_id"
name="partner_id"
type="select"
field-label="Partner"
:options="formData.partners.data || []"
track-by="id"
option-label="name"
:loading="formData.partners.loading"
data-testid="setup-trial-partner"
/>
<!-- Opportunity Sync Period -->
<AppFormField
:disabled="!requireSyncPeriod"
v-model="formState.opportunity_sync_period"
name="opportunity_sync_period"
type="select"
field-label="Import Opportunities Sync Period"
:required="requireSyncPeriod"
:rules="requireSyncPeriod ? 'required' : ''"
:options="syncPeriodOptions"
track-by="id"
option-label="label"
data-testid="setup-trial-sync-period"
/>
<!-- Calendar -->
<AppFormField
v-model="formState.calendar"
name="calendar"
type="radios"
ui="radios"
field-label="Calendar"
:required="true"
rules="required"
:options="formData.calendarOptions.data || []"
data-testid="setup-trial-calendar"
:disabled="flags.ownerCreated"
/>
<!-- Softphone -->
<div>
<div :class="[$style.fieldLabel, drawerStyle.fieldLabel]">
Softphone
</div>
<AppFormField
v-model="formState.features"
name="softphone"
type="checkbox"
:value="SOFTPHONE_FEATURE_ID"
:field-label="jiminnyVoiceLabel"
data-testid="setup-trial-softphone"
/>
</div>
<EditTeamAddressFields
v-if="softphoneEnabled"
:disabled="flags.billingDisabled"
/>
</div>
<div :class="$style.tearsGrid">
<div :class="$style.sectionTitle">
<div :class="drawerStyle.sectionTitle">Tiers & Add-ons</div>
<AppButton
icon="question"
label="Tiers explained"
mods="seamless link primary"
href="[URL_WITH_CREDENTIALS]
import useAppForm, {
SilentFormError,
} from "@/components/shared/AppFormElements/useAppForm";
import AppForm from "@/components/shared/AppFormElements/AppForm.vue";
import AppFormField from "@/components/shared/AppFormElements/AppFormField.vue";
import useAsyncData from "@/composables/useAsyncData";
import EditTeamAddressFields from "./EditTeamAddressFields.vue";
import AppDrawerModal from "@/components/shared/modals/AppDrawerModal.vue";
import { useDrawerModal } from "@/composables/useDrawerModal";
import { promptModal } from "jenesius-vue-modal";
import ChangeOwnerConfirmModal from "@/components/Settings/OrgSettings/Members/ChangeOwnerConfirmModal.vue";
import EventBus from "@/utils/event-bus";
import { getFeaturesData } from "./features";
import FeaturesGroup from "./FeaturesGroup.vue";
import FeaturesList from "./FeaturesList.vue";
import { ErrorMessage, useField } from "vee-validate";
import AppButton from "@/components/shared/Buttons/AppButton.vue";
import { useBrandedI18n } from "@/composables/useBrandedI18n";
// Define props
const props = defineProps({
data: {
type: Object,
required: true,
},
teamId: String,
});
const { tb } = useBrandedI18n();
// Branded i18n computed ref
const jiminnyVoiceLabel = tb("kiosk.edit-team.jiminny-voice--whitelabel");
const flags = reactive({
teamCreated: computed(() => !!props.data.id),
ownerCreated: computed(() => !!props.data.owner_id),
billingDisabled: computed(
() =>
!!props.data.id && props.data?.features?.includes(SOFTPHONE_FEATURE_ID),
),
});
// Setup form
const form = useAppForm({
onSubmit,
toastSuccess: flags.teamCreated
? "Account updated successfully!"
: "Account created successfully!",
});
// Setup form state with initial values
const {
formState,
hasChanges,
updateSnapshot,
exportFormState,
softphoneEnabled,
} = useEditTeamForm(props.data);
// Load required data
const formData = reactive({
calendarOptions: useAsyncData(getCalendars, { showError: true }),
crmOptions: useAsyncData(getCrmServices, { showError: true }),
features: useAsyncData(getFeaturesData, { showError: true }),
partners: useAsyncData(getPartners, { showError: true }),
admins: reactive(useAdminsList()),
});
const { close } = useDrawerModal({ onClose });
const { tierModel, featuresGroups } = useFeaturesManager();
const { requireSyncPeriod } = useRequireSyncPeriod();
const drawerAttrs = computed(() => ({
as: AppForm,
title: flags.teamCreated ? "Edit Organization" : "Setup Account",
headerButtons: [
{
type: "submit",
label: "Save",
variant: "primary",
"data-testid": "setup-trial-submit",
disabled: !unref(hasChanges),
},
],
contentAttrs: {
busy: Object.values(formData).some(({ loading }) => loading),
},
}));
function onClose() {
return modalDiscardGuard({
onSave: form.submitHandler,
hasChanges: unref(hasChanges),
});
}
async function onSubmit() {
const ownerChanged =
flags.ownerCreated && formState.value.owner_id !== props.data.owner_id;
if (ownerChanged) {
const confirmed = await promptModal(ChangeOwnerConfirmModal);
if (!confirmed) throw new SilentFormError("Owner change not confirmed");
}
const data = exportFormState();
// create or update the team
!flags.teamCreated
? await axios.post("/api/v1/settings/organizations", data)
: await axios.put(`/api/v1/kiosk/organizations/${props.data.id}`, data);
EventBus.$emit("team.updated");
// update form snapshot
updateSnapshot();
close();
}
function useFeaturesManager() {
const tierField = useField("tier_id", "required", {
initialValue: unref(formState).tier_id,
});
const tierModel = computed({
get() {
return unref(formState).tier_id;
},
set(tierId) {
setTier(tierId);
tierField.value.value = tierId;
},
});
const featuresGroups = computed(() => {
const { groups } = formData.features.data || {};
if (!groups) return [];
return [groups.TIER, groups["ADD_ON"]].filter(Boolean).flat();
});
function setTier(tierId) {
const selectedFeatures = new Set(unref(formState).features);
const { features, tiers } = formData.features.data;
// clear all tier features
features.byType.TIER.forEach(({ id }) => selectedFeatures.delete(id));
const tier = tiers.find((tier) => tier.id === tierId);
// select only selected tiers features
[...tier.inherits, tierId]
.map((tierId) => features.byTier[tierId] || [])
.flat()
.forEach((feature) => selectedFeatures.add(feature.id));
Object.assign(unref(formState), {
features: Array.from(selectedFeatures),
tier_id: tierId,
});
}
return { tierModel, setTier, featuresGroups };
}
function useRequireSyncPeriod() {
// Computed property to check if opportunity sync period is required
const requireSyncPeriod = computed(() => {
return !!formData.crmOptions.data?.find(
(item) => formState.value.crm === item.id,
)?.requireInitialSyncPeriod;
});
watch(requireSyncPeriod, (required) => {
formState.value.opportunity_sync_period = required
? formState.value.opportunity_sync_period ||
DEFAULT_OPPORTUNITY_SYNC_PERIOD
: null;
});
return { requireSyncPeriod };
}
function useAdminsList() {
return useAsyncData(async () => {
const data = await fetchUsersData(props.data.id);
return data.filter((user) => user.roles?.some((e) => e.name == "admin"));
});
}
</script>
<style lang="less" module>
.fieldLabel:has(~ * :disabled) {
opacity: 0.6;
}
.tearsGrid {
display: grid;
padding-top: 10px;
gap: 10px;
.sectionTitle {
margin-top: 30px;
display: flex;
justify-content: space-between;
}
}
.errorMessage {
color: var(--color-danger);
}
.docsRef {
font-size: 14px;
}
</style>
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v2\Api\ActivitiesApi;
use Pipedrive\versions\v2\Api\ActivityFieldsApi;
use Pipedrive\versions\v2\Api\DealFieldsApi;
use Pipedrive\versions\v2\Api\DealsApi;
use Pipedrive\versions\v2\Api\PersonFieldsApi;
use Pipedrive\versions\v2\Api\PersonsApi;
use Pipedrive\versions\v2\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$this->info('Test 2a: Get Deals');
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// v2 SDK might have different method names
// Try common v2 method names
try {
$result = $apiInstance->getDeals(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', true, "Retrieved deals in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllPersons(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "Retrieved persons in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// v2 SDK might have different method names
try {
$result = $apiInstance->getActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
// Try alternative method names
try {
$result = $apiInstance->getAllActivities(['limit' => 10]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "Retrieved activities in {$elapsed}ms", $elapsed);
} catch (Exception $e2) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, "Method not found: {$e->getMessage()}", $elapsed);
}
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49814
|
1771
|
0
|
2026-05-18T07:00:08.037883+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087608037_m1.jpg...
|
PhpStorm
|
faVsco.js – CreateTeamRequest.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 5 m left100% <28• Mon 18 May 10:00:07Nikolay Yankov (Presenting)AA3+BI018Platform Team %.Q Search boardNotify the user it adeleted but is used in AJ..AJ REPORTSBacklog[ JY-206763 aa00=deieted but is used in AJReportAJREPORTSBacklogД JY-206151%000Upgrade BE Ibraries - MayMAINTENANICSKacoeE JY-19958suggestionsAUTO-DETEGTED ACTIVITY TYPGDockoeP JY-204702 ***=*0AQ0:0SR83 JmX PrOAtte XI83 MC x (Sch x Cur x | * Cu x 0os x | 0 im x QMC x 3 Po xnny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613008 Bdt 0©* Claudea sewy X utasa Insights & Coachin— DevPJI-1ESS1 1 JT-201SAllow owner's role to be selected when setting up a trialIn Dev vImprove Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and emall to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialo put the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single select•this oouon shoulont acoca wnen cottino an oroanisaborAssignee@ Lukas KovalikAssign to meE Galya Dimitrova• Quick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAooSwotKLinked work itemsAod linked work ibenDevelc omenQ Open with VS CodeIJ Create branch4 Create commitComponentsPlatformnood comteansSuggest a reply.Status update...Thanks..Add optionsQ8•Mon 18 May 10:00Group: QueriesAJ Panorama for CallScoring in OD(AUTOMATEO AI SCORINGDeployedД 3-20361 05[Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 |1 01 ***=Setup test coverage forProphet in Sonarsepricated Gemini modeis© 31-20272Sidekick SMS issueDeployedCЕ P4-20091n •=@Nikolay Yankov10:00 AM | Daily - Platform→Lukas Kovalik13:42...
|
NULL
|
-444679030954509262
|
NULL
|
click
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comDaily - Platform • 5 m left100% <28• Mon 18 May 10:00:07Nikolay Yankov (Presenting)AA3+BI018Platform Team %.Q Search boardNotify the user it adeleted but is used in AJ..AJ REPORTSBacklog[ JY-206763 aa00=deieted but is used in AJReportAJREPORTSBacklogД JY-206151%000Upgrade BE Ibraries - MayMAINTENANICSKacoeE JY-19958suggestionsAUTO-DETEGTED ACTIVITY TYPGDockoeP JY-204702 ***=*0AQ0:0SR83 JmX PrOAtte XI83 MC x (Sch x Cur x | * Cu x 0os x | 0 im x QMC x 3 Po xnny.atlassian.net/jra/software/c/projects/JJY/boards/37?selectedissue=JY-20613008 Bdt 0©* Claudea sewy X utasa Insights & Coachin— DevPJI-1ESS1 1 JT-201SAllow owner's role to be selected when setting up a trialIn Dev vImprove Story~ Details~ DescriptionStoyan is seeing more cases where the Owner doesn't want to connect their calendar and emall to Jiminny. This isbecause they don't want to be a recorder. Currently when a trial is created we glve the Owner a Recorder role by default.In most cases he really needs to be a recorder.• allow Implementations to select the role of the owner when setting up a trialo put the field bellow the Owner emall fieldthe choices should only be - Recorder, Recorder & Voice, Analyst• single select•this oouon shoulont acoca wnen cottino an oroanisaborAssignee@ Lukas KovalikAssign to meE Galya Dimitrova• Quick start developmentUink this work item to your codeby including keys when creatinga branch, commit, or pull requestbelow. Learn moreDismissSubtasksAooSwotKLinked work itemsAod linked work ibenDevelc omenQ Open with VS CodeIJ Create branch4 Create commitComponentsPlatformnood comteansSuggest a reply.Status update...Thanks..Add optionsQ8•Mon 18 May 10:00Group: QueriesAJ Panorama for CallScoring in OD(AUTOMATEO AI SCORINGDeployedД 3-20361 05[Deadline 25 May) Migratedepricated Gemini 3.1 FlashDeployedД л-20880 |1 01 ***=Setup test coverage forProphet in Sonarsepricated Gemini modeis© 31-20272Sidekick SMS issueDeployedCЕ P4-20091n •=@Nikolay Yankov10:00 AM | Daily - Platform→Lukas Kovalik13:42...
|
49813
|
NULL
|
NULL
|
NULL
|
|
49815
|
1772
|
0
|
2026-05-18T07:00:08.037933+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087608037_m2.jpg...
|
PhpStorm
|
faVsco.js – CreateTeamRequest.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormVIewINavicareCodeLaravelKeractorFV faVsco. PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js°° pipedrive-sdk-poclooolsude> D build> D config>@ contrib> @ database>@ docsv @ front-end• .vscode› O.yarn• → coverage_ node_modules>D publicresourcesu scriotsW sromassets• M AiRenortsM connectD dashboardD DealinsightsM errorDadecM eynort-nortalMeytencion-inctalledM Invitationonboard→ olavoacka olavlistsv Settinas• Mtests_• M ActivitiesSearch• → AutomatedReports> M MobileAorv D modalsv M EditTeamModall• M tects |C ActivityController.ongconvertLeadActivitles.ongo syncriannat.ongc createrlaybookcreatedevent.ongc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohp© PlanhatActivityListener.php(C)AskAnvthinaPromotService.ohd(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv(C) AutomatedReportkesultonpEditTeamModal.vue XKtemplate:<AppDrawerModal v-bind="drawerAttrs" #default="{ $style: drawerStyle }">ediv •clacc-iidnawenStvlo formGnidil,<div :class="drawerStyle.sectionTitle">General</div><AppFormFieldtleld- Label="company name'v-model="tormstate.namelrules="requzred"data-testid="setun-trial-name"<-- Owner Emanl --,<ApoFormFieldv-ife""flaas. ownercreated"tvne="emanl"field-label="Owner Fmail"V-model="formState ownen emai]"reaurrede"true"name="ownen email"rules="required|email"data-tectid="cetun-tnial-ounen-ema.]"<AppFormFieldv-elsefield-lahel="Nwnen"namo-llownen id"l:required="true'rules="requ1red"w-modol-llGonmCtoto nunon idlloptions="formData.admins.data 11 []"tyoe="selontnV EditTeamAddreccFields vueVCditToamModal vuatrack-by="id"is fonturoc icdata-testid="setup-trial-owner-emam"V FeaturesGroup.vue=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmuse Pipedrive verszons vz Ap1 ACCIviclesAp1use Pipedrive\versions\v2\Api ActivityFieldsApi:use Pipedrave versions vz Ap1 Leaurielasapluse Pipedrive\versions\v2 \Api\DealsApi:use Pipedrive versions vz Ap1 Personrlelasap1use Pipedrive verszons Vz Ap1 Personsap1.use Pipedrive versions vz contzquration.11 usage22124 6t26 6t32 đ124protected Ssignature = "11m1nnv:test-p1pedrive-officral-sok teamid-'*protected Sdescrintion = ITest official Pinedrive SDK (oinedrive/pinedrive) with exiorivate arrav Sresults = 13lusageprivate EncryptedTokenManager $tokenManager:no usagespublic function __construct(EncryptedTokenManager $tokenManager)parent:: construct?).sthls->cokennanager = scokenmanager;public function handled: intf...}private function runTests(int SteamId): void{...}1 usageprivate function test0AuthInitialization(SocialAccount SsocialAccount): voidf...?1 usageorivate function testBasicCrudOperations(SocialAccount SsocialAccount: void$this->info( string: 'Test 2: Basic CRUD Operations'):tny-Il Get the naw token from datahaseSnawhhToken = SsocialAccount->ae+ProviderilsenToken0-.strlen(SrawDbToken)."")•Trial Owner Role SelecNot Shown when editingModal used for botn create/editOwner gets selected role + AdminAlways gets Admin + RecorderKeplace Uppontuniy sync Perlod locatlolCurrently at lines 71-84Dart of Greate TeamHandled in SditTeamModalImplementation PlanFrontend Changes1. EditTeamModal.vue• Add role selection tield below Owner email (after line 39Onlv show when creatina team ( Iflaas.teamGreated )• Move Opportunity Sync Period field to 3rd row, 1st column (after CRM field)Add role options: Recorder, Recorder & Voice, Analyst• Add owner role to form state1. CreateTeamRequest.oho• Add validation rule for ouner role field• Allowed values: recorder, recorder and voice, analyst• Onlv required when creatina (not editina)2. UserinvitationDTO::forOwner()• Accept owner_role parameter from request• Map role name to role IDAlways add ROLE_ADMIN to the role IDs (as per requirement: "selected role + Admin permissions")• Replace hardcoded ROLE RECORDER with selected role3. EditTeamRequest.php• Ensure ouner role is NOT acceoted when editina (validation should reiect it)Key Files to Modify1. /front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue3./app/DT0/Inv1tation/UserInv1tat1onDT0.php4./app/Htto/Requests/Settinas/Teams/EdiitTeamRequest.ohoTectina Considerationc•Test role assignment for all 3 options (Recorder, Recorder & Voice, Analyst)Verity Admin permission is alwavs addedEnsure field is hidden when editing existing team• Verify Opportunity Sync Period moves to correct location• Test owner sign-in flow with each role option#Daily - Platform - 5 m left100% 5• Mon 18 May 10:00:07U AskJiminnyReportActivityServiceTest v+0 ..Condition: v-ir="!Tlags. teamcreated"Modify UserInvitationDT0:: for0wner() to use selected role + AdminMove Opportunity Sync Period, add role field in its placesame component handles bothAsk anvthina (&4-L)SWF.16Cal aW Windsurf Team1-1.UTE.8Po 2 spaces...
|
NULL
|
-3397107257152378446
|
NULL
|
click
|
ocr
|
NULL
|
PhostormVIewINavicareCodeLaravelKeractorFV faVsco. PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js°° pipedrive-sdk-poclooolsude> D build> D config>@ contrib> @ database>@ docsv @ front-end• .vscode› O.yarn• → coverage_ node_modules>D publicresourcesu scriotsW sromassets• M AiRenortsM connectD dashboardD DealinsightsM errorDadecM eynort-nortalMeytencion-inctalledM Invitationonboard→ olavoacka olavlistsv Settinas• Mtests_• M ActivitiesSearch• → AutomatedReports> M MobileAorv D modalsv M EditTeamModall• M tects |C ActivityController.ongconvertLeadActivitles.ongo syncriannat.ongc createrlaybookcreatedevent.ongc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohp© PlanhatActivityListener.php(C)AskAnvthinaPromotService.ohd(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv(C) AutomatedReportkesultonpEditTeamModal.vue XKtemplate:<AppDrawerModal v-bind="drawerAttrs" #default="{ $style: drawerStyle }">ediv •clacc-iidnawenStvlo formGnidil,<div :class="drawerStyle.sectionTitle">General</div><AppFormFieldtleld- Label="company name'v-model="tormstate.namelrules="requzred"data-testid="setun-trial-name"<-- Owner Emanl --,<ApoFormFieldv-ife""flaas. ownercreated"tvne="emanl"field-label="Owner Fmail"V-model="formState ownen emai]"reaurrede"true"name="ownen email"rules="required|email"data-tectid="cetun-tnial-ounen-ema.]"<AppFormFieldv-elsefield-lahel="Nwnen"namo-llownen id"l:required="true'rules="requ1red"w-modol-llGonmCtoto nunon idlloptions="formData.admins.data 11 []"tyoe="selontnV EditTeamAddreccFields vueVCditToamModal vuatrack-by="id"is fonturoc icdata-testid="setup-trial-owner-emam"V FeaturesGroup.vue=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmuse Pipedrive verszons vz Ap1 ACCIviclesAp1use Pipedrive\versions\v2\Api ActivityFieldsApi:use Pipedrave versions vz Ap1 Leaurielasapluse Pipedrive\versions\v2 \Api\DealsApi:use Pipedrive versions vz Ap1 Personrlelasap1use Pipedrive verszons Vz Ap1 Personsap1.use Pipedrive versions vz contzquration.11 usage22124 6t26 6t32 đ124protected Ssignature = "11m1nnv:test-p1pedrive-officral-sok teamid-'*protected Sdescrintion = ITest official Pinedrive SDK (oinedrive/pinedrive) with exiorivate arrav Sresults = 13lusageprivate EncryptedTokenManager $tokenManager:no usagespublic function __construct(EncryptedTokenManager $tokenManager)parent:: construct?).sthls->cokennanager = scokenmanager;public function handled: intf...}private function runTests(int SteamId): void{...}1 usageprivate function test0AuthInitialization(SocialAccount SsocialAccount): voidf...?1 usageorivate function testBasicCrudOperations(SocialAccount SsocialAccount: void$this->info( string: 'Test 2: Basic CRUD Operations'):tny-Il Get the naw token from datahaseSnawhhToken = SsocialAccount->ae+ProviderilsenToken0-.strlen(SrawDbToken)."")•Trial Owner Role SelecNot Shown when editingModal used for botn create/editOwner gets selected role + AdminAlways gets Admin + RecorderKeplace Uppontuniy sync Perlod locatlolCurrently at lines 71-84Dart of Greate TeamHandled in SditTeamModalImplementation PlanFrontend Changes1. EditTeamModal.vue• Add role selection tield below Owner email (after line 39Onlv show when creatina team ( Iflaas.teamGreated )• Move Opportunity Sync Period field to 3rd row, 1st column (after CRM field)Add role options: Recorder, Recorder & Voice, Analyst• Add owner role to form state1. CreateTeamRequest.oho• Add validation rule for ouner role field• Allowed values: recorder, recorder and voice, analyst• Onlv required when creatina (not editina)2. UserinvitationDTO::forOwner()• Accept owner_role parameter from request• Map role name to role IDAlways add ROLE_ADMIN to the role IDs (as per requirement: "selected role + Admin permissions")• Replace hardcoded ROLE RECORDER with selected role3. EditTeamRequest.php• Ensure ouner role is NOT acceoted when editina (validation should reiect it)Key Files to Modify1. /front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue3./app/DT0/Inv1tation/UserInv1tat1onDT0.php4./app/Htto/Requests/Settinas/Teams/EdiitTeamRequest.ohoTectina Considerationc•Test role assignment for all 3 options (Recorder, Recorder & Voice, Analyst)Verity Admin permission is alwavs addedEnsure field is hidden when editing existing team• Verify Opportunity Sync Period moves to correct location• Test owner sign-in flow with each role option#Daily - Platform - 5 m left100% 5• Mon 18 May 10:00:07U AskJiminnyReportActivityServiceTest v+0 ..Condition: v-ir="!Tlags. teamcreated"Modify UserInvitationDT0:: for0wner() to use selected role + AdminMove Opportunity Sync Period, add role field in its placesame component handles bothAsk anvthina (&4-L)SWF.16Cal aW Windsurf Team1-1.UTE.8Po 2 spaces...
|
49812
|
NULL
|
NULL
|
NULL
|