|
11055
|
219
|
18
|
2026-04-14T09:10:17.905774+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157817905_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-249341903282119781
|
-8276470947908459549
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProjectvToolsWindowHelpD AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph® ReportSort.php(e) Reporisonbirection.Kloskservice.php> M Mail• MeetingGeneratorO NotificationD OAuth2D RecallAl[ SecurityC StrategyStreamingD TeamTelephonyUserPilotM Webhook© AbstractService.php© ActivityProviderFactory.ph|© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php© IpapiClient.php© IpapiService.php© ParticipantShareService.ph© PlanhatService.php© PlaybackService.phpPlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorInterface.© ResolveTeamCrmConnecti© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php©TeamService.php© TranscodeParameterResol'© UserService.php© Uuid.php> C Traits› D UseCases> D User> D Utils• I validationv MVO~ D Repositoryv @ OnDemandActivitySears© Criteria.php© TranscriptionKeywordP:lests passed: (a minute ago© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© Criteria.phpAskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityServicenutdieeynocoutourere ainisenesonitActivityUpdatedDate::PARAM_UPDATED_FROM,ActivityUpdatedDate: :PARAM_UPDATED_TO,© TrackProviderInstalledEvent.phpClosingPeriodFilter::KEY_START_DATE,© CreateActivityLoggedEvent.php© UserPilotActivityListener.phpClosingPeriodFilter::KEY_END_DATE,(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php11411511611711811912012111241 usagepublic function __constructCprivate readonly ActivitySearch SactivitySearch,privace readonly Elascicactivitykeposicory pelasclckeposicory.class Automacedкeрortskepo o:A15 X4 ^onwvare reaconly Loccerinuerace nLoddera) 6...3/**/*** Retrieve all standard (non-Ask Jiminny) m 38* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.39* Date filters stored on the saved search are excluded; if no other filters exist,* @param string $sortColumnThe column to40* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* dparam string ssortulrection ine sort dire41—42* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**= Criteria: :createFromRequest(* Retrieve all Ask Liminny reports createdAAccept meyeet$requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page: =* OodrdllusernusenThe user whos 51array_merge (SrequestParams,['Limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page']* @param string $sortColumnThe column t,52nuser-poernezone* Oparam string $sortDirection The sort dire53):* @return Collection<AutomatedReport>*/14 usages57public function getAskJiminnyReportsByUser(User $user,-59string $sortColumn = 'created_at',surno ssortutreccion = 'desc'): Collection {...J2 usagesprivate function buildSortedQuery(string $sor65/**-67* Get all active and enabled reports with ac—68* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>-7123 usagespublic function getActiveReportsByFrequency(s74* Oreturn string[] Activity IDs*/14 usagespublic function getActivitvIdsForSavedSearchdsearch ssavedsearch,user suser,): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyRepQrt] Fetched activity IDs for saved search', ['saved_search_id'→> $savedSearch->getId(),'user_id' => Suser-›getid(),'acuvity count'= count nacuvitviosi1):return SactivityIds:1 usageprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);toreacn Usaveosearch›getFilters() as $filter) €+key - эt-pcerngeuriuger Accept File &+X Reject File 0*€Support Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:17CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leams55:00uir-o( 4 spaces...
|
11054
|
|
11057
|
219
|
19
|
2026-04-14T09:10:20.910565+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157820910_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelpD AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph® ReportSort.php(e) Reporisonbirection.Kloskservice.php> M Mail• MeetingGeneratorNotificationDJ OAuth2D RecallAlD SecurityC StrategyStreamingD TeamTelephonyUserPilotM Webhook© AbstractService.php© ActivityProviderFactory.ph|© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php©IpapiClient.php©IpapiService.php© ParticipantShareService.ph© PlanhatService.php© PlaybackService.phpPlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorInterface.© ResolveTeamCrmConnecti© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php©TeamService.php© TranscodeParameterResol© UserService.php© Uuid.php› D Traits› D UseCases> D UserDUtils• I validationvIVO~ D Repositoryv @ OnDemandActivitySearc© Criteria.php© TranscriptionKeywordP:Tests passed: 1 (a minute ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php xAskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© Criteria.php<?phpdeclare(strict_types=1);(e TrackProvidernstallled-vent.ononamespace Jiminny\Component\ActivitySearch\Service;© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpuseclass ActivitySearchclass Automacedкeрortskepo o:815 X4 л83114115116117118119120121123/*** Retrieve all standard (non-Ask Jiminny) M107* @param string $sortColumnThe column tc* Cparam string ssortDirection The sort dir 109* @return Collection<AutomatedReport>11111212 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}113114115116 F1171/*** Retrieve all Ask Liminay reports created {119* Oodrdll usernusenIne user Ynos* @param string $sortColumnIne corumn cc* Oparam string $sortDirection The sort dire197* @return Collection<AutomatedReport>198*/—19914 usages200public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',surno ssortutreccion = 'desc'): Collection {...J2074254233234—2352 usages236private function buildSortedQuery(string $sor]237— 244/**245* Get all active and enabled reports with ac247* @param string $frequency148* dreturh coLcectzon<aucomaredкeport.L0723 usages260public function getActiveReportsByFrequency(s)7 usagesprivate Container $container;public function __construct(Container $container){.}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):/*** pretuea str ingt)9 usagespublic function getArrayFilterKeys(User $consumer): array{...;1 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollec1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}1 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:20CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filters•der aculvicvids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ctivitvourationRande → min duration = 1 Ttlters ouf o-second acrivitiesi• ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leamsTO/'2uir-o( 4 spaces...
|
NULL
|
-8044268755507340865
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelpD AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph® ReportSort.php(e) Reporisonbirection.Kloskservice.php> M Mail• MeetingGeneratorNotificationDJ OAuth2D RecallAlD SecurityC StrategyStreamingD TeamTelephonyUserPilotM Webhook© AbstractService.php© ActivityProviderFactory.ph|© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php©IpapiClient.php©IpapiService.php© ParticipantShareService.ph© PlanhatService.php© PlaybackService.phpPlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorInterface.© ResolveTeamCrmConnecti© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php©TeamService.php© TranscodeParameterResol© UserService.php© Uuid.php› D Traits› D UseCases> D UserDUtils• I validationvIVO~ D Repositoryv @ OnDemandActivitySearc© Criteria.php© TranscriptionKeywordP:Tests passed: 1 (a minute ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php xAskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© Criteria.php<?phpdeclare(strict_types=1);(e TrackProvidernstallled-vent.ononamespace Jiminny\Component\ActivitySearch\Service;© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpuseclass ActivitySearchclass Automacedкeрortskepo o:815 X4 л83114115116117118119120121123/*** Retrieve all standard (non-Ask Jiminny) M107* @param string $sortColumnThe column tc* Cparam string ssortDirection The sort dir 109* @return Collection<AutomatedReport>11111212 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}113114115116 F1171/*** Retrieve all Ask Liminay reports created {119* Oodrdll usernusenIne user Ynos* @param string $sortColumnIne corumn cc* Oparam string $sortDirection The sort dire197* @return Collection<AutomatedReport>198*/—19914 usages200public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',surno ssortutreccion = 'desc'): Collection {...J2074254233234—2352 usages236private function buildSortedQuery(string $sor]237— 244/**245* Get all active and enabled reports with ac247* @param string $frequency148* dreturh coLcectzon<aucomaredкeport.L0723 usages260public function getActiveReportsByFrequency(s)7 usagesprivate Container $container;public function __construct(Container $container){.}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):/*** pretuea str ingt)9 usagespublic function getArrayFilterKeys(User $consumer): array{...;1 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollec1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}1 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:20CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filters•der aculvicvids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ctivitvourationRande → min duration = 1 Ttlters ouf o-second acrivitiesi• ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leamsTO/'2uir-o( 4 spaces...
|
NULL
|
|
11060
|
219
|
20
|
2026-04-14T09:10:30.946999+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157830946_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivitySearch.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\Service;
use Illuminate\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinition\AiCallScoreFilter;
use Jiminny\Component\ActivitySearch\FilterDefinition\AutoScoreFilter;
use Jiminny\Component\ActivitySearch\FilterDefinition\ClosedDealsFilter;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealCloseDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\HasTopicTriggersFilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinition\PlaybackTopicFilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictActivityChannel;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictPublicActivitiesOnly;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictTeam;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictUserActive;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictUserGroupScope;
use Jiminny\Component\ActivitySearch\FilterDefinition\TeamInsights\TopicFilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\User;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Repositories\Crm\LayoutRepository;
use Jiminny\Services\TeamService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
class ActivitySearch
{
private Container $container;
public function __construct(Container $container)
{
$this->container = $container;
}
public function getOnDemandPageFilters(): FilterDefinitionCollection
{
return FilterDefinitionCollection::make(
Collection::make([
// special case filters
FilterDefinition\ActivityStatusIn::class,
FilterDefinition\ActivityUpdatedDate::class,
FilterDefinition\ActivityRecordingStopped::class,
FilterDefinition\ActivityFilter::class,
FilterDefinition\ExternalId::class,
FilterDefinition\NudgeRunId::class,
FilterDefinition\ParticipantUserIn::class,
FilterDefinition\PartnerFilterDefinition::class,
// healthy restrictions
RestrictTeam::class,
RestrictUserGroupScope::class,
RestrictActivityChannel::class,
RestrictUserActive::class,
FilterDefinition\Security\PrivateMeetingsForCurrentUserOnly::class,
// regular filters
FilterDefinition\ActivityActualDate::class,
FilterDefinition\ActivityChannel::class,
FilterDefinition\ActivityDurationRange::class,
FilterDefinition\ActivityPlaylistIn::class,
FilterDefinition\ActivityProviderIn::class,
FilterDefinition\ActivityRecorded::class,
FilterDefinition\ActivityType::class,
FilterDefinition\CoachingFeedbackAverageScore::class,
AutoScoreFilter::class,
AiCallScoreFilter::class,
FilterDefinition\CoachingFeedbackCoachUserIn::class,
FilterDefinition\CrmFieldCollection::class,
FilterDefinition\CurrentStage::class,
FilterDefinition\Customer::class,
FilterDefinition\CustomerMonologueDuration::class,
FilterDefinition\CustomerQuestionCount::class,
FilterDefinition\DealAge::class,
DealCloseDate::class,
FilterDefinition\DealValue::class,
FilterDefinition\EngagingQuestionCount::class,
FilterDefinition\ShowInternalExternalActivitiesFilter::class,
FilterDefinition\HasTranscription::class,
FilterDefinition\InsightfulQuestionCount::class,
FilterDefinition\LanguageFilterDefinition::class,
FilterDefinition\LoggedToCrm::class,
FilterDefinition\OrganiserGroupIn:[PASSWORD]
FilterDefinition\OrganiserUserIn::class,
FilterDefinition\PatienceRange::class,
PlaybackTopicFilterDefinition::class,
FilterDefinition\ProviderFilterDefinition::class,
FilterDefinition\SortBy::class,
FilterDefinition\SpeechRate::class,
FilterDefinition\StageAtCallFilterDefinition::class,
FilterDefinition\TalkTimeRatio::class,
FilterDefinition\TeamMemberUserIn::class,
FilterDefinition\TranscriptionComposite::class,
FilterDefinition\UserMonologueDuration::class,
FilterDefinition\UserQuestionCount::class,
FilterDefinition\CommentCountRange::class,
FilterDefinition\HasPendingAiCrmNotes::class,
])
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
}
public function getOnDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection
{
return $this
->getOnDemandPageFilters()
->withCriteria($criteria)
->withConsumer($consumer)
->withRestrictions($consumer->getTeam());
}
/**
* @return string[]
*/
public function getArrayFilterKeys(User $consumer): array
{
return $this
->getOnDemandPageFilters()
->withConsumer($consumer)
->getPropertyTypes([FilterDefinitionCollection::PROPERTY_TYPE_ARRAY])
->keys()
->filter(static fn (string $key): bool => ! str_contains($key, '.'))
->values()
->all();
}
private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollection
{
$dateRangeFilterClass = $isExport
? FilterDefinition\TeamInsights\ConversationExport\DateRangeFilter::class
: FilterDefinition\TeamInsights\DateRangeFilter::class;
return FilterDefinitionCollection::make(
Collection::make([
// special cases
$dateRangeFilterClass,
FilterDefinition\TeamInsights\Exists::class,
// healthy restrictions
RestrictTeam::class,
RestrictUserGroupScope::class,
RestrictActivityChannel::class,
RestrictPublicActivitiesOnly::class,
RestrictUserActive::class,
// regular filters
FilterDefinition\ActivityChannel::class,
FilterDefinition\TeamInsights\ActivityDurationRange::class,
FilterDefinition\ActivityPlaylistIn::class,
FilterDefinition\ActivityProviderIn::class,
FilterDefinition\TeamInsights\ActivityRecorded::class,
FilterDefinition\ActivityType::class,
FilterDefinition\CoachingFeedbackAverageScore::class,
AutoScoreFilter::class,
AiCallScoreFilter::class,
FilterDefinition\CoachingFeedbackCoachUserIn::class,
FilterDefinition\CrmFieldCollection::class,
FilterDefinition\Customer::class,
FilterDefinition\CurrentStage::class,
FilterDefinition\CustomerMonologueDuration::class,
FilterDefinition\CustomerQuestionCount::class,
FilterDefinition\DealAge::class,
DealCloseDate::class,
FilterDefinition\DealValue::class,
FilterDefinition\EngagingQuestionCount::class,
FilterDefinition\ShowInternalExternalActivitiesFilter::class,
FilterDefinition\InsightfulQuestionCount::class,
FilterDefinition\LanguageFilterDefinition::class,
FilterDefinition\LoggedToCrm::class,
FilterDefinition\TeamInsights\UserInFilter::class,
FilterDefinition\TeamInsights\UserGroupInFilter::class,
FilterDefinition\PatienceRange::class,
PlaybackTopicFilterDefinition::class,
FilterDefinition\ProviderFilterDefinition::class,
FilterDefinition\SortBy::class,
FilterDefinition\SpeechRate::class,
FilterDefinition\StageAtCallFilterDefinition::class,
FilterDefinition\TalkTimeRatio::class,
FilterDefinition\TeamMemberUserIn::class,
FilterDefinition\TranscriptionComposite::class,
FilterDefinition\UserMonologueDuration::class,
FilterDefinition\UserQuestionCount::class,
FilterDefinition\CommentCountRange::class,
// Relevant for topics in deals.
ClosedDealsFilter::class,
HasTopicTriggersFilterDefinition::class,
TopicFilterDefinition::class,
])
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
}
private function getDealInsightsPageFilters(
bool $useCreatedDate = false,
bool $includeDealType = false,
bool $includePipeline = false,
): FilterDefinitionCollection {
if ($useCreatedDate) {
$periodFilterClass = FilterDefinition\DealInsights\CreatedPeriodFilter::class;
} else {
$periodFilterClass = FilterDefinition\DealInsights\ClosingPeriodFilter::class;
}
$filterSet = [
RestrictTeam::class,
$periodFilterClass,
FilterDefinition\DealInsights\UserInFilter::class,
FilterDefinition\DealInsights\UserGroupInFilter::class,
FilterDefinition\DealInsights\DealStageInFilter::class,
FilterDefinition\DealInsights\DealNameFilter::class,
];
if ($includePipeline) {
$filterSet[] = FilterDefinition\DealInsights\DealPipelineInFilter::class;
}
if ($includeDealType) {
$filterSet[] = FilterDefinition\DealInsights\DealTypeInFilter::class;
}
return FilterDefinitionCollection::make(
Collection::make($filterSet)
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
}
public function getTeamInsightsPageFilterSet(
Criteria $criteria,
User $consumer,
bool $isExport = false
): FilterDefinitionCollection {
return $this
->getTeamInsightsPageFilters($isExport)
->withCriteria($criteria)
->withConsumer($consumer)
->withRestrictions($consumer->getTeam());
}
public function getDealInsightsPageFilterSet(
Criteria $criteria,
User $consumer
): FilterDefinitionCollection {
$includeDealType = $this->shouldIncludeDealType($consumer);
$includePipeline = $this->shouldIncludePipeline($consumer);
$useCreatedDate = $this->shouldUseCreatedDate($consumer);
return $this
->getDealInsightsPageFilters($useCreatedDate, $includeDealType, $includePipeline)
->withCriteria($criteria)
->withConsumer($consumer);
}
public function getTeamAiAutomationFilterSet(
Criteria $criteria,
User $consumer
): FilterDefinitionCollection {
return $this
->getTeamAiAutomationPageFilterSet()
->withCriteria($criteria)
->withConsumer($consumer);
}
private function getTeamAiAutomationPageFilterSet(): FilterDefinitionCollection
{
$filterSet = [
RestrictTeam::class,
FilterDefinition\DealInsights\DealStageInFilter::class,
];
return FilterDefinitionCollection::make(
Collection::make($filterSet)
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
}
public function getHomepageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection
{
$filterDefinitionCollection = FilterDefinitionCollection::make(
Collection::make([
RestrictTeam::class,
RestrictUserGroupScope::class,
RestrictActivityChannel::class,
RestrictUserActive::class,
FilterDefinition\Security\PrivateMeetingsForCurrentUserOnly::class,
FilterDefinition\ActivityActualDate::class,
FilterDefinition\Customer::class,
FilterDefinition\ActivityChannel::class,
FilterDefinition\ActivityDurationRange::class,
FilterDefinition\ActivityProviderIn::class,
FilterDefinition\ActivityRecorded::class,
FilterDefinition\ActivityRecordingStopped::class,
FilterDefinition\ActivityScheduledDate::class,
FilterDefinition\ActivityStatusIn::class,
FilterDefinition\LoggedToCrm::class,
FilterDefinition\OrganiserUserIn::class,
FilterDefinition\OrganiserUserNotIn::class,
FilterDefinition\ProviderFilterDefinition::class,
FilterDefinition\SortBy::class,
FilterDefinition\UserGroupInOptionalFilter::class,
FilterDefinition\OnlyActiveUsers::class,
])
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
$filterDefinitionCollection->withCriteria($criteria);
$filterDefinitionCollection->withConsumer($consumer);
return $filterDefinitionCollection;
}
public function getPartnerFilterSet(Criteria $criteria): FilterDefinitionCollection
{
$filterDefinitionCollection = FilterDefinitionCollection::make(
Collection::make([
RestrictActivityChannel::class,
FilterDefinition\OrganiserTeamIn::class,
FilterDefinition\ActivityUpdatedDate::class,
FilterDefinition\ActivityStatusIn::class,
FilterDefinition\SortBy::class,
])
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all()
);
$filterDefinitionCollection->withCriteria($criteria);
return $filterDefinitionCollection;
}
private function shouldIncludeDealType(User $user): bool
{
$crmConfig = $user->getTeam()->getCrmConfiguration();
$crmProviderName = $crmConfig->getProviderName();
if (! array_key_exists($crmProviderName, Field::BUSINESS_TYPE_FIELDS)) {
return false;
}
$layoutRepository = app(LayoutRepository::class);
$layoutFields = $layoutRepository->getDealInsightLayoutFields($crmConfig);
$dealTypeField = Field::BUSINESS_TYPE_FIELDS[$crmProviderName];
if (! in_array($dealTypeField, $layoutFields)) {
return false;
}
return true;
}
private function shouldIncludePipeline(User $user): bool
{
$crmConfig = $user->getTeam()->getCrmConfiguration();
$crmProviderName = $crmConfig->getProviderName();
if (in_array($crmProviderName, [
Configuration::PROVIDER_SALESFORCE,
Configuration::PROVIDER_INTEGRATION_APP,
])) {
return false;
}
return true;
}
private function shouldUseCreatedDate(User $user): bool
{
$teamService = app(TeamService::class);
return ! $teamService->useDealInsightsClosedDateFilter($user->getTeam());
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\Service;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\AiCallScoreFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\AutoScoreFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ClosedDealsFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealCloseDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\HasTopicTriggersFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\PlaybackTopicFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictActivityChannel;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictPublicActivitiesOnly;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictTeam;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictUserActive;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictUserGroupScope;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\TeamInsights\\TopicFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Repositories\\Crm\\LayoutRepository;\nuse Jiminny\\Services\\TeamService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\n\nclass ActivitySearch\n{\n private Container $container;\n\n public function __construct(Container $container)\n {\n $this->container = $container;\n }\n\n public function getOnDemandPageFilters(): FilterDefinitionCollection\n {\n return FilterDefinitionCollection::make(\n Collection::make([\n // special case filters\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\ActivityUpdatedDate::class,\n FilterDefinition\\ActivityRecordingStopped::class,\n FilterDefinition\\ActivityFilter::class,\n FilterDefinition\\ExternalId::class,\n FilterDefinition\\NudgeRunId::class,\n FilterDefinition\\ParticipantUserIn::class,\n FilterDefinition\\PartnerFilterDefinition::class,\n\n // healthy restrictions\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictUserActive::class,\n FilterDefinition\\Security\\PrivateMeetingsForCurrentUserOnly::class,\n\n // regular filters\n FilterDefinition\\ActivityActualDate::class,\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\ActivityDurationRange::class,\n FilterDefinition\\ActivityPlaylistIn::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\ActivityRecorded::class,\n FilterDefinition\\ActivityType::class,\n FilterDefinition\\CoachingFeedbackAverageScore::class,\n AutoScoreFilter::class,\n AiCallScoreFilter::class,\n FilterDefinition\\CoachingFeedbackCoachUserIn::class,\n FilterDefinition\\CrmFieldCollection::class,\n FilterDefinition\\CurrentStage::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\CustomerMonologueDuration::class,\n FilterDefinition\\CustomerQuestionCount::class,\n FilterDefinition\\DealAge::class,\n DealCloseDate::class,\n FilterDefinition\\DealValue::class,\n FilterDefinition\\EngagingQuestionCount::class,\n FilterDefinition\\ShowInternalExternalActivitiesFilter::class,\n FilterDefinition\\HasTranscription::class,\n FilterDefinition\\InsightfulQuestionCount::class,\n FilterDefinition\\LanguageFilterDefinition::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\OrganiserGroupIn::class,\n FilterDefinition\\OrganiserUserIn::class,\n FilterDefinition\\PatienceRange::class,\n PlaybackTopicFilterDefinition::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\SpeechRate::class,\n FilterDefinition\\StageAtCallFilterDefinition::class,\n FilterDefinition\\TalkTimeRatio::class,\n FilterDefinition\\TeamMemberUserIn::class,\n FilterDefinition\\TranscriptionComposite::class,\n FilterDefinition\\UserMonologueDuration::class,\n FilterDefinition\\UserQuestionCount::class,\n FilterDefinition\\CommentCountRange::class,\n FilterDefinition\\HasPendingAiCrmNotes::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getOnDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection\n {\n return $this\n ->getOnDemandPageFilters()\n ->withCriteria($criteria)\n ->withConsumer($consumer)\n ->withRestrictions($consumer->getTeam());\n }\n\n /**\n * @return string[]\n */\n public function getArrayFilterKeys(User $consumer): array\n {\n return $this\n ->getOnDemandPageFilters()\n ->withConsumer($consumer)\n ->getPropertyTypes([FilterDefinitionCollection::PROPERTY_TYPE_ARRAY])\n ->keys()\n ->filter(static fn (string $key): bool => ! str_contains($key, '.'))\n ->values()\n ->all();\n }\n\n private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollection\n {\n $dateRangeFilterClass = $isExport\n ? FilterDefinition\\TeamInsights\\ConversationExport\\DateRangeFilter::class\n : FilterDefinition\\TeamInsights\\DateRangeFilter::class;\n\n return FilterDefinitionCollection::make(\n Collection::make([\n // special cases\n $dateRangeFilterClass,\n FilterDefinition\\TeamInsights\\Exists::class,\n\n // healthy restrictions\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictPublicActivitiesOnly::class,\n RestrictUserActive::class,\n\n // regular filters\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\TeamInsights\\ActivityDurationRange::class,\n FilterDefinition\\ActivityPlaylistIn::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\TeamInsights\\ActivityRecorded::class,\n FilterDefinition\\ActivityType::class,\n FilterDefinition\\CoachingFeedbackAverageScore::class,\n AutoScoreFilter::class,\n AiCallScoreFilter::class,\n FilterDefinition\\CoachingFeedbackCoachUserIn::class,\n FilterDefinition\\CrmFieldCollection::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\CurrentStage::class,\n FilterDefinition\\CustomerMonologueDuration::class,\n FilterDefinition\\CustomerQuestionCount::class,\n FilterDefinition\\DealAge::class,\n DealCloseDate::class,\n FilterDefinition\\DealValue::class,\n FilterDefinition\\EngagingQuestionCount::class,\n FilterDefinition\\ShowInternalExternalActivitiesFilter::class,\n FilterDefinition\\InsightfulQuestionCount::class,\n FilterDefinition\\LanguageFilterDefinition::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\TeamInsights\\UserInFilter::class,\n FilterDefinition\\TeamInsights\\UserGroupInFilter::class,\n FilterDefinition\\PatienceRange::class,\n PlaybackTopicFilterDefinition::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\SpeechRate::class,\n FilterDefinition\\StageAtCallFilterDefinition::class,\n FilterDefinition\\TalkTimeRatio::class,\n FilterDefinition\\TeamMemberUserIn::class,\n FilterDefinition\\TranscriptionComposite::class,\n FilterDefinition\\UserMonologueDuration::class,\n FilterDefinition\\UserQuestionCount::class,\n FilterDefinition\\CommentCountRange::class,\n // Relevant for topics in deals.\n ClosedDealsFilter::class,\n HasTopicTriggersFilterDefinition::class,\n TopicFilterDefinition::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n private function getDealInsightsPageFilters(\n bool $useCreatedDate = false,\n bool $includeDealType = false,\n bool $includePipeline = false,\n ): FilterDefinitionCollection {\n if ($useCreatedDate) {\n $periodFilterClass = FilterDefinition\\DealInsights\\CreatedPeriodFilter::class;\n } else {\n $periodFilterClass = FilterDefinition\\DealInsights\\ClosingPeriodFilter::class;\n }\n\n $filterSet = [\n RestrictTeam::class,\n $periodFilterClass,\n FilterDefinition\\DealInsights\\UserInFilter::class,\n FilterDefinition\\DealInsights\\UserGroupInFilter::class,\n FilterDefinition\\DealInsights\\DealStageInFilter::class,\n FilterDefinition\\DealInsights\\DealNameFilter::class,\n ];\n\n if ($includePipeline) {\n $filterSet[] = FilterDefinition\\DealInsights\\DealPipelineInFilter::class;\n }\n\n if ($includeDealType) {\n $filterSet[] = FilterDefinition\\DealInsights\\DealTypeInFilter::class;\n }\n\n return FilterDefinitionCollection::make(\n Collection::make($filterSet)\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getTeamInsightsPageFilterSet(\n Criteria $criteria,\n User $consumer,\n bool $isExport = false\n ): FilterDefinitionCollection {\n return $this\n ->getTeamInsightsPageFilters($isExport)\n ->withCriteria($criteria)\n ->withConsumer($consumer)\n ->withRestrictions($consumer->getTeam());\n }\n\n public function getDealInsightsPageFilterSet(\n Criteria $criteria,\n User $consumer\n ): FilterDefinitionCollection {\n $includeDealType = $this->shouldIncludeDealType($consumer);\n $includePipeline = $this->shouldIncludePipeline($consumer);\n $useCreatedDate = $this->shouldUseCreatedDate($consumer);\n\n return $this\n ->getDealInsightsPageFilters($useCreatedDate, $includeDealType, $includePipeline)\n ->withCriteria($criteria)\n ->withConsumer($consumer);\n }\n\n public function getTeamAiAutomationFilterSet(\n Criteria $criteria,\n User $consumer\n ): FilterDefinitionCollection {\n return $this\n ->getTeamAiAutomationPageFilterSet()\n ->withCriteria($criteria)\n ->withConsumer($consumer);\n }\n\n private function getTeamAiAutomationPageFilterSet(): FilterDefinitionCollection\n {\n $filterSet = [\n RestrictTeam::class,\n FilterDefinition\\DealInsights\\DealStageInFilter::class,\n ];\n\n return FilterDefinitionCollection::make(\n Collection::make($filterSet)\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getHomepageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection\n {\n $filterDefinitionCollection = FilterDefinitionCollection::make(\n Collection::make([\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictUserActive::class,\n FilterDefinition\\Security\\PrivateMeetingsForCurrentUserOnly::class,\n FilterDefinition\\ActivityActualDate::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\ActivityDurationRange::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\ActivityRecorded::class,\n FilterDefinition\\ActivityRecordingStopped::class,\n FilterDefinition\\ActivityScheduledDate::class,\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\OrganiserUserIn::class,\n FilterDefinition\\OrganiserUserNotIn::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\UserGroupInOptionalFilter::class,\n FilterDefinition\\OnlyActiveUsers::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n $filterDefinitionCollection->withCriteria($criteria);\n $filterDefinitionCollection->withConsumer($consumer);\n\n return $filterDefinitionCollection;\n }\n\n public function getPartnerFilterSet(Criteria $criteria): FilterDefinitionCollection\n {\n $filterDefinitionCollection = FilterDefinitionCollection::make(\n Collection::make([\n RestrictActivityChannel::class,\n FilterDefinition\\OrganiserTeamIn::class,\n FilterDefinition\\ActivityUpdatedDate::class,\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\SortBy::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all()\n );\n $filterDefinitionCollection->withCriteria($criteria);\n\n return $filterDefinitionCollection;\n }\n\n private function shouldIncludeDealType(User $user): bool\n {\n $crmConfig = $user->getTeam()->getCrmConfiguration();\n $crmProviderName = $crmConfig->getProviderName();\n\n if (! array_key_exists($crmProviderName, Field::BUSINESS_TYPE_FIELDS)) {\n return false;\n }\n\n $layoutRepository = app(LayoutRepository::class);\n $layoutFields = $layoutRepository->getDealInsightLayoutFields($crmConfig);\n $dealTypeField = Field::BUSINESS_TYPE_FIELDS[$crmProviderName];\n\n if (! in_array($dealTypeField, $layoutFields)) {\n return false;\n }\n\n return true;\n }\n\n private function shouldIncludePipeline(User $user): bool\n {\n $crmConfig = $user->getTeam()->getCrmConfiguration();\n $crmProviderName = $crmConfig->getProviderName();\n\n if (in_array($crmProviderName, [\n Configuration::PROVIDER_SALESFORCE,\n Configuration::PROVIDER_INTEGRATION_APP,\n ])) {\n return false;\n }\n\n return true;\n }\n\n private function shouldUseCreatedDate(User $user): bool\n {\n $teamService = app(TeamService::class);\n\n return ! $teamService->useDealInsightsClosedDateFilter($user->getTeam());\n }\n}","depth":4,"bounds":{"left":0.32617188,"top":0.12777779,"width":0.34101564,"height":0.8722222},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\Service;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\AiCallScoreFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\AutoScoreFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ClosedDealsFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealCloseDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\HasTopicTriggersFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\PlaybackTopicFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictActivityChannel;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictPublicActivitiesOnly;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictTeam;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictUserActive;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictUserGroupScope;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\TeamInsights\\TopicFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Repositories\\Crm\\LayoutRepository;\nuse Jiminny\\Services\\TeamService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\n\nclass ActivitySearch\n{\n private Container $container;\n\n public function __construct(Container $container)\n {\n $this->container = $container;\n }\n\n public function getOnDemandPageFilters(): FilterDefinitionCollection\n {\n return FilterDefinitionCollection::make(\n Collection::make([\n // special case filters\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\ActivityUpdatedDate::class,\n FilterDefinition\\ActivityRecordingStopped::class,\n FilterDefinition\\ActivityFilter::class,\n FilterDefinition\\ExternalId::class,\n FilterDefinition\\NudgeRunId::class,\n FilterDefinition\\ParticipantUserIn::class,\n FilterDefinition\\PartnerFilterDefinition::class,\n\n // healthy restrictions\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictUserActive::class,\n FilterDefinition\\Security\\PrivateMeetingsForCurrentUserOnly::class,\n\n // regular filters\n FilterDefinition\\ActivityActualDate::class,\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\ActivityDurationRange::class,\n FilterDefinition\\ActivityPlaylistIn::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\ActivityRecorded::class,\n FilterDefinition\\ActivityType::class,\n FilterDefinition\\CoachingFeedbackAverageScore::class,\n AutoScoreFilter::class,\n AiCallScoreFilter::class,\n FilterDefinition\\CoachingFeedbackCoachUserIn::class,\n FilterDefinition\\CrmFieldCollection::class,\n FilterDefinition\\CurrentStage::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\CustomerMonologueDuration::class,\n FilterDefinition\\CustomerQuestionCount::class,\n FilterDefinition\\DealAge::class,\n DealCloseDate::class,\n FilterDefinition\\DealValue::class,\n FilterDefinition\\EngagingQuestionCount::class,\n FilterDefinition\\ShowInternalExternalActivitiesFilter::class,\n FilterDefinition\\HasTranscription::class,\n FilterDefinition\\InsightfulQuestionCount::class,\n FilterDefinition\\LanguageFilterDefinition::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\OrganiserGroupIn::class,\n FilterDefinition\\OrganiserUserIn::class,\n FilterDefinition\\PatienceRange::class,\n PlaybackTopicFilterDefinition::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\SpeechRate::class,\n FilterDefinition\\StageAtCallFilterDefinition::class,\n FilterDefinition\\TalkTimeRatio::class,\n FilterDefinition\\TeamMemberUserIn::class,\n FilterDefinition\\TranscriptionComposite::class,\n FilterDefinition\\UserMonologueDuration::class,\n FilterDefinition\\UserQuestionCount::class,\n FilterDefinition\\CommentCountRange::class,\n FilterDefinition\\HasPendingAiCrmNotes::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getOnDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection\n {\n return $this\n ->getOnDemandPageFilters()\n ->withCriteria($criteria)\n ->withConsumer($consumer)\n ->withRestrictions($consumer->getTeam());\n }\n\n /**\n * @return string[]\n */\n public function getArrayFilterKeys(User $consumer): array\n {\n return $this\n ->getOnDemandPageFilters()\n ->withConsumer($consumer)\n ->getPropertyTypes([FilterDefinitionCollection::PROPERTY_TYPE_ARRAY])\n ->keys()\n ->filter(static fn (string $key): bool => ! str_contains($key, '.'))\n ->values()\n ->all();\n }\n\n private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollection\n {\n $dateRangeFilterClass = $isExport\n ? FilterDefinition\\TeamInsights\\ConversationExport\\DateRangeFilter::class\n : FilterDefinition\\TeamInsights\\DateRangeFilter::class;\n\n return FilterDefinitionCollection::make(\n Collection::make([\n // special cases\n $dateRangeFilterClass,\n FilterDefinition\\TeamInsights\\Exists::class,\n\n // healthy restrictions\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictPublicActivitiesOnly::class,\n RestrictUserActive::class,\n\n // regular filters\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\TeamInsights\\ActivityDurationRange::class,\n FilterDefinition\\ActivityPlaylistIn::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\TeamInsights\\ActivityRecorded::class,\n FilterDefinition\\ActivityType::class,\n FilterDefinition\\CoachingFeedbackAverageScore::class,\n AutoScoreFilter::class,\n AiCallScoreFilter::class,\n FilterDefinition\\CoachingFeedbackCoachUserIn::class,\n FilterDefinition\\CrmFieldCollection::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\CurrentStage::class,\n FilterDefinition\\CustomerMonologueDuration::class,\n FilterDefinition\\CustomerQuestionCount::class,\n FilterDefinition\\DealAge::class,\n DealCloseDate::class,\n FilterDefinition\\DealValue::class,\n FilterDefinition\\EngagingQuestionCount::class,\n FilterDefinition\\ShowInternalExternalActivitiesFilter::class,\n FilterDefinition\\InsightfulQuestionCount::class,\n FilterDefinition\\LanguageFilterDefinition::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\TeamInsights\\UserInFilter::class,\n FilterDefinition\\TeamInsights\\UserGroupInFilter::class,\n FilterDefinition\\PatienceRange::class,\n PlaybackTopicFilterDefinition::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\SpeechRate::class,\n FilterDefinition\\StageAtCallFilterDefinition::class,\n FilterDefinition\\TalkTimeRatio::class,\n FilterDefinition\\TeamMemberUserIn::class,\n FilterDefinition\\TranscriptionComposite::class,\n FilterDefinition\\UserMonologueDuration::class,\n FilterDefinition\\UserQuestionCount::class,\n FilterDefinition\\CommentCountRange::class,\n // Relevant for topics in deals.\n ClosedDealsFilter::class,\n HasTopicTriggersFilterDefinition::class,\n TopicFilterDefinition::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n private function getDealInsightsPageFilters(\n bool $useCreatedDate = false,\n bool $includeDealType = false,\n bool $includePipeline = false,\n ): FilterDefinitionCollection {\n if ($useCreatedDate) {\n $periodFilterClass = FilterDefinition\\DealInsights\\CreatedPeriodFilter::class;\n } else {\n $periodFilterClass = FilterDefinition\\DealInsights\\ClosingPeriodFilter::class;\n }\n\n $filterSet = [\n RestrictTeam::class,\n $periodFilterClass,\n FilterDefinition\\DealInsights\\UserInFilter::class,\n FilterDefinition\\DealInsights\\UserGroupInFilter::class,\n FilterDefinition\\DealInsights\\DealStageInFilter::class,\n FilterDefinition\\DealInsights\\DealNameFilter::class,\n ];\n\n if ($includePipeline) {\n $filterSet[] = FilterDefinition\\DealInsights\\DealPipelineInFilter::class;\n }\n\n if ($includeDealType) {\n $filterSet[] = FilterDefinition\\DealInsights\\DealTypeInFilter::class;\n }\n\n return FilterDefinitionCollection::make(\n Collection::make($filterSet)\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getTeamInsightsPageFilterSet(\n Criteria $criteria,\n User $consumer,\n bool $isExport = false\n ): FilterDefinitionCollection {\n return $this\n ->getTeamInsightsPageFilters($isExport)\n ->withCriteria($criteria)\n ->withConsumer($consumer)\n ->withRestrictions($consumer->getTeam());\n }\n\n public function getDealInsightsPageFilterSet(\n Criteria $criteria,\n User $consumer\n ): FilterDefinitionCollection {\n $includeDealType = $this->shouldIncludeDealType($consumer);\n $includePipeline = $this->shouldIncludePipeline($consumer);\n $useCreatedDate = $this->shouldUseCreatedDate($consumer);\n\n return $this\n ->getDealInsightsPageFilters($useCreatedDate, $includeDealType, $includePipeline)\n ->withCriteria($criteria)\n ->withConsumer($consumer);\n }\n\n public function getTeamAiAutomationFilterSet(\n Criteria $criteria,\n User $consumer\n ): FilterDefinitionCollection {\n return $this\n ->getTeamAiAutomationPageFilterSet()\n ->withCriteria($criteria)\n ->withConsumer($consumer);\n }\n\n private function getTeamAiAutomationPageFilterSet(): FilterDefinitionCollection\n {\n $filterSet = [\n RestrictTeam::class,\n FilterDefinition\\DealInsights\\DealStageInFilter::class,\n ];\n\n return FilterDefinitionCollection::make(\n Collection::make($filterSet)\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getHomepageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection\n {\n $filterDefinitionCollection = FilterDefinitionCollection::make(\n Collection::make([\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictUserActive::class,\n FilterDefinition\\Security\\PrivateMeetingsForCurrentUserOnly::class,\n FilterDefinition\\ActivityActualDate::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\ActivityDurationRange::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\ActivityRecorded::class,\n FilterDefinition\\ActivityRecordingStopped::class,\n FilterDefinition\\ActivityScheduledDate::class,\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\OrganiserUserIn::class,\n FilterDefinition\\OrganiserUserNotIn::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\UserGroupInOptionalFilter::class,\n FilterDefinition\\OnlyActiveUsers::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n $filterDefinitionCollection->withCriteria($criteria);\n $filterDefinitionCollection->withConsumer($consumer);\n\n return $filterDefinitionCollection;\n }\n\n public function getPartnerFilterSet(Criteria $criteria): FilterDefinitionCollection\n {\n $filterDefinitionCollection = FilterDefinitionCollection::make(\n Collection::make([\n RestrictActivityChannel::class,\n FilterDefinition\\OrganiserTeamIn::class,\n FilterDefinition\\ActivityUpdatedDate::class,\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\SortBy::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all()\n );\n $filterDefinitionCollection->withCriteria($criteria);\n\n return $filterDefinitionCollection;\n }\n\n private function shouldIncludeDealType(User $user): bool\n {\n $crmConfig = $user->getTeam()->getCrmConfiguration();\n $crmProviderName = $crmConfig->getProviderName();\n\n if (! array_key_exists($crmProviderName, Field::BUSINESS_TYPE_FIELDS)) {\n return false;\n }\n\n $layoutRepository = app(LayoutRepository::class);\n $layoutFields = $layoutRepository->getDealInsightLayoutFields($crmConfig);\n $dealTypeField = Field::BUSINESS_TYPE_FIELDS[$crmProviderName];\n\n if (! in_array($dealTypeField, $layoutFields)) {\n return false;\n }\n\n return true;\n }\n\n private function shouldIncludePipeline(User $user): bool\n {\n $crmConfig = $user->getTeam()->getCrmConfiguration();\n $crmProviderName = $crmConfig->getProviderName();\n\n if (in_array($crmProviderName, [\n Configuration::PROVIDER_SALESFORCE,\n Configuration::PROVIDER_INTEGRATION_APP,\n ])) {\n return false;\n }\n\n return true;\n }\n\n private function shouldUseCreatedDate(User $user): bool\n {\n $teamService = app(TeamService::class);\n\n return ! $teamService->useDealInsightsClosedDateFilter($user->getTeam());\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5643224685284439189
|
-3735472194166249888
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\Service;
use Illuminate\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinition\AiCallScoreFilter;
use Jiminny\Component\ActivitySearch\FilterDefinition\AutoScoreFilter;
use Jiminny\Component\ActivitySearch\FilterDefinition\ClosedDealsFilter;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealCloseDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\HasTopicTriggersFilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinition\PlaybackTopicFilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictActivityChannel;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictPublicActivitiesOnly;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictTeam;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictUserActive;
use Jiminny\Component\ActivitySearch\FilterDefinition\Security\RestrictUserGroupScope;
use Jiminny\Component\ActivitySearch\FilterDefinition\TeamInsights\TopicFilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\User;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Repositories\Crm\LayoutRepository;
use Jiminny\Services\TeamService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
class ActivitySearch
{
private Container $container;
public function __construct(Container $container)
{
$this->container = $container;
}
public function getOnDemandPageFilters(): FilterDefinitionCollection
{
return FilterDefinitionCollection::make(
Collection::make([
// special case filters
FilterDefinition\ActivityStatusIn::class,
FilterDefinition\ActivityUpdatedDate::class,
FilterDefinition\ActivityRecordingStopped::class,
FilterDefinition\ActivityFilter::class,
FilterDefinition\ExternalId::class,
FilterDefinition\NudgeRunId::class,
FilterDefinition\ParticipantUserIn::class,
FilterDefinition\PartnerFilterDefinition::class,
// healthy restrictions
RestrictTeam::class,
RestrictUserGroupScope::class,
RestrictActivityChannel::class,
RestrictUserActive::class,
FilterDefinition\Security\PrivateMeetingsForCurrentUserOnly::class,
// regular filters
FilterDefinition\ActivityActualDate::class,
FilterDefinition\ActivityChannel::class,
FilterDefinition\ActivityDurationRange::class,
FilterDefinition\ActivityPlaylistIn::class,
FilterDefinition\ActivityProviderIn::class,
FilterDefinition\ActivityRecorded::class,
FilterDefinition\ActivityType::class,
FilterDefinition\CoachingFeedbackAverageScore::class,
AutoScoreFilter::class,
AiCallScoreFilter::class,
FilterDefinition\CoachingFeedbackCoachUserIn::class,
FilterDefinition\CrmFieldCollection::class,
FilterDefinition\CurrentStage::class,
FilterDefinition\Customer::class,
FilterDefinition\CustomerMonologueDuration::class,
FilterDefinition\CustomerQuestionCount::class,
FilterDefinition\DealAge::class,
DealCloseDate::class,
FilterDefinition\DealValue::class,
FilterDefinition\EngagingQuestionCount::class,
FilterDefinition\ShowInternalExternalActivitiesFilter::class,
FilterDefinition\HasTranscription::class,
FilterDefinition\InsightfulQuestionCount::class,
FilterDefinition\LanguageFilterDefinition::class,
FilterDefinition\LoggedToCrm::class,
FilterDefinition\OrganiserGroupIn:[PASSWORD]
FilterDefinition\OrganiserUserIn::class,
FilterDefinition\PatienceRange::class,
PlaybackTopicFilterDefinition::class,
FilterDefinition\ProviderFilterDefinition::class,
FilterDefinition\SortBy::class,
FilterDefinition\SpeechRate::class,
FilterDefinition\StageAtCallFilterDefinition::class,
FilterDefinition\TalkTimeRatio::class,
FilterDefinition\TeamMemberUserIn::class,
FilterDefinition\TranscriptionComposite::class,
FilterDefinition\UserMonologueDuration::class,
FilterDefinition\UserQuestionCount::class,
FilterDefinition\CommentCountRange::class,
FilterDefinition\HasPendingAiCrmNotes::class,
])
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
}
public function getOnDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection
{
return $this
->getOnDemandPageFilters()
->withCriteria($criteria)
->withConsumer($consumer)
->withRestrictions($consumer->getTeam());
}
/**
* @return string[]
*/
public function getArrayFilterKeys(User $consumer): array
{
return $this
->getOnDemandPageFilters()
->withConsumer($consumer)
->getPropertyTypes([FilterDefinitionCollection::PROPERTY_TYPE_ARRAY])
->keys()
->filter(static fn (string $key): bool => ! str_contains($key, '.'))
->values()
->all();
}
private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollection
{
$dateRangeFilterClass = $isExport
? FilterDefinition\TeamInsights\ConversationExport\DateRangeFilter::class
: FilterDefinition\TeamInsights\DateRangeFilter::class;
return FilterDefinitionCollection::make(
Collection::make([
// special cases
$dateRangeFilterClass,
FilterDefinition\TeamInsights\Exists::class,
// healthy restrictions
RestrictTeam::class,
RestrictUserGroupScope::class,
RestrictActivityChannel::class,
RestrictPublicActivitiesOnly::class,
RestrictUserActive::class,
// regular filters
FilterDefinition\ActivityChannel::class,
FilterDefinition\TeamInsights\ActivityDurationRange::class,
FilterDefinition\ActivityPlaylistIn::class,
FilterDefinition\ActivityProviderIn::class,
FilterDefinition\TeamInsights\ActivityRecorded::class,
FilterDefinition\ActivityType::class,
FilterDefinition\CoachingFeedbackAverageScore::class,
AutoScoreFilter::class,
AiCallScoreFilter::class,
FilterDefinition\CoachingFeedbackCoachUserIn::class,
FilterDefinition\CrmFieldCollection::class,
FilterDefinition\Customer::class,
FilterDefinition\CurrentStage::class,
FilterDefinition\CustomerMonologueDuration::class,
FilterDefinition\CustomerQuestionCount::class,
FilterDefinition\DealAge::class,
DealCloseDate::class,
FilterDefinition\DealValue::class,
FilterDefinition\EngagingQuestionCount::class,
FilterDefinition\ShowInternalExternalActivitiesFilter::class,
FilterDefinition\InsightfulQuestionCount::class,
FilterDefinition\LanguageFilterDefinition::class,
FilterDefinition\LoggedToCrm::class,
FilterDefinition\TeamInsights\UserInFilter::class,
FilterDefinition\TeamInsights\UserGroupInFilter::class,
FilterDefinition\PatienceRange::class,
PlaybackTopicFilterDefinition::class,
FilterDefinition\ProviderFilterDefinition::class,
FilterDefinition\SortBy::class,
FilterDefinition\SpeechRate::class,
FilterDefinition\StageAtCallFilterDefinition::class,
FilterDefinition\TalkTimeRatio::class,
FilterDefinition\TeamMemberUserIn::class,
FilterDefinition\TranscriptionComposite::class,
FilterDefinition\UserMonologueDuration::class,
FilterDefinition\UserQuestionCount::class,
FilterDefinition\CommentCountRange::class,
// Relevant for topics in deals.
ClosedDealsFilter::class,
HasTopicTriggersFilterDefinition::class,
TopicFilterDefinition::class,
])
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
}
private function getDealInsightsPageFilters(
bool $useCreatedDate = false,
bool $includeDealType = false,
bool $includePipeline = false,
): FilterDefinitionCollection {
if ($useCreatedDate) {
$periodFilterClass = FilterDefinition\DealInsights\CreatedPeriodFilter::class;
} else {
$periodFilterClass = FilterDefinition\DealInsights\ClosingPeriodFilter::class;
}
$filterSet = [
RestrictTeam::class,
$periodFilterClass,
FilterDefinition\DealInsights\UserInFilter::class,
FilterDefinition\DealInsights\UserGroupInFilter::class,
FilterDefinition\DealInsights\DealStageInFilter::class,
FilterDefinition\DealInsights\DealNameFilter::class,
];
if ($includePipeline) {
$filterSet[] = FilterDefinition\DealInsights\DealPipelineInFilter::class;
}
if ($includeDealType) {
$filterSet[] = FilterDefinition\DealInsights\DealTypeInFilter::class;
}
return FilterDefinitionCollection::make(
Collection::make($filterSet)
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
}
public function getTeamInsightsPageFilterSet(
Criteria $criteria,
User $consumer,
bool $isExport = false
): FilterDefinitionCollection {
return $this
->getTeamInsightsPageFilters($isExport)
->withCriteria($criteria)
->withConsumer($consumer)
->withRestrictions($consumer->getTeam());
}
public function getDealInsightsPageFilterSet(
Criteria $criteria,
User $consumer
): FilterDefinitionCollection {
$includeDealType = $this->shouldIncludeDealType($consumer);
$includePipeline = $this->shouldIncludePipeline($consumer);
$useCreatedDate = $this->shouldUseCreatedDate($consumer);
return $this
->getDealInsightsPageFilters($useCreatedDate, $includeDealType, $includePipeline)
->withCriteria($criteria)
->withConsumer($consumer);
}
public function getTeamAiAutomationFilterSet(
Criteria $criteria,
User $consumer
): FilterDefinitionCollection {
return $this
->getTeamAiAutomationPageFilterSet()
->withCriteria($criteria)
->withConsumer($consumer);
}
private function getTeamAiAutomationPageFilterSet(): FilterDefinitionCollection
{
$filterSet = [
RestrictTeam::class,
FilterDefinition\DealInsights\DealStageInFilter::class,
];
return FilterDefinitionCollection::make(
Collection::make($filterSet)
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
}
public function getHomepageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection
{
$filterDefinitionCollection = FilterDefinitionCollection::make(
Collection::make([
RestrictTeam::class,
RestrictUserGroupScope::class,
RestrictActivityChannel::class,
RestrictUserActive::class,
FilterDefinition\Security\PrivateMeetingsForCurrentUserOnly::class,
FilterDefinition\ActivityActualDate::class,
FilterDefinition\Customer::class,
FilterDefinition\ActivityChannel::class,
FilterDefinition\ActivityDurationRange::class,
FilterDefinition\ActivityProviderIn::class,
FilterDefinition\ActivityRecorded::class,
FilterDefinition\ActivityRecordingStopped::class,
FilterDefinition\ActivityScheduledDate::class,
FilterDefinition\ActivityStatusIn::class,
FilterDefinition\LoggedToCrm::class,
FilterDefinition\OrganiserUserIn::class,
FilterDefinition\OrganiserUserNotIn::class,
FilterDefinition\ProviderFilterDefinition::class,
FilterDefinition\SortBy::class,
FilterDefinition\UserGroupInOptionalFilter::class,
FilterDefinition\OnlyActiveUsers::class,
])
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all(),
);
$filterDefinitionCollection->withCriteria($criteria);
$filterDefinitionCollection->withConsumer($consumer);
return $filterDefinitionCollection;
}
public function getPartnerFilterSet(Criteria $criteria): FilterDefinitionCollection
{
$filterDefinitionCollection = FilterDefinitionCollection::make(
Collection::make([
RestrictActivityChannel::class,
FilterDefinition\OrganiserTeamIn::class,
FilterDefinition\ActivityUpdatedDate::class,
FilterDefinition\ActivityStatusIn::class,
FilterDefinition\SortBy::class,
])
->map(fn (string $className): FilterDefinition => $this->container->make($className))
->all()
);
$filterDefinitionCollection->withCriteria($criteria);
return $filterDefinitionCollection;
}
private function shouldIncludeDealType(User $user): bool
{
$crmConfig = $user->getTeam()->getCrmConfiguration();
$crmProviderName = $crmConfig->getProviderName();
if (! array_key_exists($crmProviderName, Field::BUSINESS_TYPE_FIELDS)) {
return false;
}
$layoutRepository = app(LayoutRepository::class);
$layoutFields = $layoutRepository->getDealInsightLayoutFields($crmConfig);
$dealTypeField = Field::BUSINESS_TYPE_FIELDS[$crmProviderName];
if (! in_array($dealTypeField, $layoutFields)) {
return false;
}
return true;
}
private function shouldIncludePipeline(User $user): bool
{
$crmConfig = $user->getTeam()->getCrmConfiguration();
$crmProviderName = $crmConfig->getProviderName();
if (in_array($crmProviderName, [
Configuration::PROVIDER_SALESFORCE,
Configuration::PROVIDER_INTEGRATION_APP,
])) {
return false;
}
return true;
}
private function shouldUseCreatedDate(User $user): bool
{
$teamService = app(TeamService::class);
return ! $teamService->useDealInsightsClosedDateFilter($user->getTeam());
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11057
|
|
11062
|
219
|
21
|
2026-04-14T09:10:32.033016+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157832033_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpyJiminnyDeouecommana.ongv Service© ActivityApiSearch.ph© ActivitySearch.php© UserOptionsByGrour© AbstractStageFilterDefilActivitySearchServicePrC DeallnsightsPeriodFilter0 DealinsidnisPeriodrilteng FilterDetinition.phpc rterverntoncolecto© FilterDefinitionQuery.ph© FilterDefinitionQueryCol• FilteredValueContainerli© IntMinMaxRange.php[ AiActivityType[ AiAutomationD AiCallScoringD AskAnythingD AskJiminnyAiDAWSM BillinaManagementM Cache• CoachingFeedback> D CountryD CustomerApi• DatabaseC DatadogC DateTimeDeallnsights_ DealRisksEasticsearch>_tloquent> DEncoding> D EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystemD GeckoD GongGuzzleHttpKeyPoints• KioskM LanquageDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot• MobileSettings| ModelNotiticationNudgeParagraphBreakerM ParticipantSpeechPartitionedCookieD PlaybackPagePlaylistThrssl-dAulomaleakeporscommand.ono© AutomatedReportsSendCommand.phpAddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpsrono(e TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Component\ActivitySearch\Service;© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 л› use ...class ActivitvSearch591141151161171181191201211124123lests passed: (a minute ago/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnIne column tc-oe* Oparam string $sortDirection The sort dire 107-108*orerurn cocuectonsauromareonedor10912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**114113114115116117* Retrieve all Ask Liminny reports created 2118* OodrdllusernusenThe user whos 119* @param string $sortColumnThe column tc 130* Oparam string $sortDirection The sort dire1151* Oreturn Collection<AutomatedReport>1Y114 usagespublic function getAskJiminnyReportsByUser(199User $user,-200string $sortColumn = 'created_at',string ssorcbirection = "desc"202): Collection {...J232253Z usages/**1254private function buildSortedQuery(string $sor235250237* Get all active and enabled reports with ac244245* @param string $frequency246247* dreturh coLcectzon<aucomacedкeрort>24825823 usagespublic function getActiveReportsByFrequency(:2597 usagesprivate Container $container;public function __construct(Container $container)f...}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function getOnDemandPageFilterSet(Criteria $criteria, User Sconsumer): FilterDefinitreturn $this->getOnDemandPageFilters()->nunenainchuerlay->withConsumer ($consumer)->withRestrictions($consumer->getTeam()):9 usagespublic function getArrayFilterKeys(User $consumer): arrayf..31 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,bool $includeDealType = false,bool $includePipeline = false,): FilterDefinitionCollection {.+public function getTeamInsightsPageFilterSet(cricerta pcracerta,user +consumer,bool sisExport = false): FilterDefinitionCollection {...public function getDealInsightsPageFilterSet(Criteria $criteria,User $consumer): FalterDefinitionCollection{..1 usagepubLic tunccion getleamAlAucomationriltersectSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:31CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuPo/ape/a/ports/ASkJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tilterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturnee o.Fix: AskJiminnyReportActivityService.php:51 —added 'sequence_number' → 1 to the Criteria: :createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6W Windsurf Teams11T:Z0uir-o( 4 spaces...
|
NULL
|
-3162346501202244887
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpyJiminnyDeouecommana.ongv Service© ActivityApiSearch.ph© ActivitySearch.php© UserOptionsByGrour© AbstractStageFilterDefilActivitySearchServicePrC DeallnsightsPeriodFilter0 DealinsidnisPeriodrilteng FilterDetinition.phpc rterverntoncolecto© FilterDefinitionQuery.ph© FilterDefinitionQueryCol• FilteredValueContainerli© IntMinMaxRange.php[ AiActivityType[ AiAutomationD AiCallScoringD AskAnythingD AskJiminnyAiDAWSM BillinaManagementM Cache• CoachingFeedback> D CountryD CustomerApi• DatabaseC DatadogC DateTimeDeallnsights_ DealRisksEasticsearch>_tloquent> DEncoding> D EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystemD GeckoD GongGuzzleHttpKeyPoints• KioskM LanquageDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot• MobileSettings| ModelNotiticationNudgeParagraphBreakerM ParticipantSpeechPartitionedCookieD PlaybackPagePlaylistThrssl-dAulomaleakeporscommand.ono© AutomatedReportsSendCommand.phpAddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpsrono(e TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Component\ActivitySearch\Service;© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 л› use ...class ActivitvSearch591141151161171181191201211124123lests passed: (a minute ago/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnIne column tc-oe* Oparam string $sortDirection The sort dire 107-108*orerurn cocuectonsauromareonedor10912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**114113114115116117* Retrieve all Ask Liminny reports created 2118* OodrdllusernusenThe user whos 119* @param string $sortColumnThe column tc 130* Oparam string $sortDirection The sort dire1151* Oreturn Collection<AutomatedReport>1Y114 usagespublic function getAskJiminnyReportsByUser(199User $user,-200string $sortColumn = 'created_at',string ssorcbirection = "desc"202): Collection {...J232253Z usages/**1254private function buildSortedQuery(string $sor235250237* Get all active and enabled reports with ac244245* @param string $frequency246247* dreturh coLcectzon<aucomacedкeрort>24825823 usagespublic function getActiveReportsByFrequency(:2597 usagesprivate Container $container;public function __construct(Container $container)f...}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function getOnDemandPageFilterSet(Criteria $criteria, User Sconsumer): FilterDefinitreturn $this->getOnDemandPageFilters()->nunenainchuerlay->withConsumer ($consumer)->withRestrictions($consumer->getTeam()):9 usagespublic function getArrayFilterKeys(User $consumer): arrayf..31 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,bool $includeDealType = false,bool $includePipeline = false,): FilterDefinitionCollection {.+public function getTeamInsightsPageFilterSet(cricerta pcracerta,user +consumer,bool sisExport = false): FilterDefinitionCollection {...public function getDealInsightsPageFilterSet(Criteria $criteria,User $consumer): FalterDefinitionCollection{..1 usagepubLic tunccion getleamAlAucomationriltersectSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:31CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuPo/ape/a/ports/ASkJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tilterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturnee o.Fix: AskJiminnyReportActivityService.php:51 —added 'sequence_number' → 1 to the Criteria: :createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6W Windsurf Teams11T:Z0uir-o( 4 spaces...
|
NULL
|
|
11064
|
219
|
22
|
2026-04-14T09:10:45.844707+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157845844_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivitySearch.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-304832669432165688
|
-8852932249833634878
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v© ReportController.phpToolsWindowHelpyJiminnyDeouecommana.ongv Service© ActivityApiSearch.ph© ActivitySearch.php© UserOptionsByGrour© AbstractStageFilterDefilActivitySearchServicePrC DeallnsightsPeriodFilter0 DealinsidnisPeriodrilteng FilterDetinition.phpc rterverntoncolecto© FilterDefinitionQuery.ph© FilterDefinitionQueryCol• FilteredValueContainerli© IntMinMaxRange.php[ AiActivityType[ AiAutomationD AiCallScoringD AskAnythingD AskJiminnyAiDAWSM BillinaManagementM Cache• CoachingFeedback> D CountryD CustomerApi• DatabaseC DatadogC DateTimeDeallnsights_ DealRisksEasticsearch>_tloquent> DEncoding> D EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystemD GeckoD GongGuzzleHttpKeyPoints• KioskM LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot• MobileSettings| ModelNotiticationNudgeParagraphBreakerM ParticipantSpeechPartitionedCookieD PlaybackPagePlaylistTnesstatAulomaleakeporscommand.ono© AutomatedReportsSendCommand.phpAddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpsrono(e) TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Component\ActivitySearch\Service;© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 л› use ...class ActivitvSearch591141151161171181191201211124123lests passed: (a minute ago/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnIne column tc-oe* Oparam string $sortDirection The sort dire 107-108*orerurn coccecclonsauromceoreooro10912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/**114113114115116117* Retrieve all Ask Liminny reports created 2118* OodrdllusernusenThe user whos 119* @param string $sortColumnThe column tc 130* Oparam string $sortDirection The sort dire1151* Oreturn Collection<AutomatedReport>1Y114 usagespublic function getAskJiminnyReportsByUser(199User $user,-200string $sortColumn = 'created_at',string ssorcbirection = "desc"202): Collection {...}232253Z usages/**1254private function buildSortedQuery(string $sor235250237* Get all active and enabled reports with ac244245* @param string $frequency246247* dreturh coLcectzon<aucomacedкeрort>24825823 usagespublic function getActiveReportsByFrequency(:2597 usagesprivate Container $container;public function __construct(Container $container)f...}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function getOnDemandPageFilterSet(Criteria $criteria, User Sconsumer): FilterDefinitreturn $this->getOnDemandPageFilters()->nunenainchuerlay->withConsumer ($consumer)->withRestrictions($consumer->getTeam()):9 usagespublic function getArrayFilterKeys(User $consumer): arrayf..31 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,bool $includeDealType = false,bool $includePipeline = false,): FilterDefinitionCollection {.+public function getTeamInsightsPageFilterSet(cricerta pcracerta,user +consumer,bool sisExport = false): FilterDefinitionCollection {...public function getDealInsightsPageFilterSet(Criteria $criteria,User $consumer): FalterDefinitionCollection{..1 usagepubLic tunccion getleamAlAucomacionriltersetlSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:45CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ..Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuPo/ape/a/ports/ASkJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturnee o.Fix: AskJiminnyReportActivityService.php:51 —added 'sequence_number' → 1 to the Criteria: :createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExap/la it to me again. Why is there issue with that+ <> Code Claude Sonnet 4.6W Windsurf Teams11T:Z0uir-o( 4 spaces...
|
11062
|
|
11066
|
219
|
23
|
2026-04-14T09:10:50.693581+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157850693_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v© ReportController.phpToolsWindowHelpyJiminnyDeouecommana.ongv Service© ActivityApiSearch.ph© ActivitySearch.php© UserOptionsByGrour© AbstractStageFilterDefilActivitySearchServicePrC DeallnsightsPeriodFilter0 DealinsidnisPeriodrilteng FilterDetinition.phpc rterverntoncolecto© FilterDefinitionQuery.ph© FilterDefinitionQueryCol• FilteredValueContainerli© IntMinMaxRange.php[ AiActivityType[ AiAutomationD AiCallScoringD AskAnythingD AskJiminnyAiDAWSM BillinaManagementM Cache• CoachingFeedback> D CountryD CustomerApi• DatabaseC DatadogC DateTimeDeallnsights_ DealRisksEasticsearch>_tloquent> DEncoding> D EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystemD GeckoD GongGuzzleHttpKeyPoints• KioskM LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot• MobileSettings| ModelNotiticationNudgeParagraphBreakerM ParticipantSpeechPartitionedCookieD PlaybackPagePlaylistTnesstatAulomaleakeporscommand.ono© AutomatedReportsSendCommand.phpAddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpsrono(e) TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Component\ActivitySearch\Service;© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 л› use ...class ActivitvSearch591141151161171181191201211124123lests passed: (a minute ago/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnIne column tc-oe* Oparam string $sortDirection The sort dire 107-108*orerurn coccecclonsauromceoreooro10912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/**114113114115116117* Retrieve all Ask Liminny reports created 2118* OodrdllusernusenThe user whos 119* @param string $sortColumnThe column tc 130* Oparam string $sortDirection The sort dire1151* Oreturn Collection<AutomatedReport>1Y114 usagespublic function getAskJiminnyReportsByUser(199User $user,-200string $sortColumn = 'created_at',string ssorcbirection = "desc"202): Collection {...}232253Z usages/**1254private function buildSortedQuery(string $sor235250237* Get all active and enabled reports with ac244245* @param string $frequency246247* dreturh coLcectzon<aucomacedкeрort>24825823 usagespublic function getActiveReportsByFrequency(:2597 usagesprivate Container $container;public function __construct(Container $container)f...}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function getOnDemandPageFilterSet(Criteria $criteria, User Sconsumer): FilterDefinitreturn $this->getOnDemandPageFilters()->nunenainchuerlay->withConsumer ($consumer)->withRestrictions($consumer->getTeam()):9 usagespublic function getArrayFilterKeys(User $consumer): arrayf..31 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,bool $includeDealType = false,bool $includePipeline = false,): FilterDefinitionCollection {.+public function getTeamInsightsPageFilterSet(cricerta pcracerta,user +consumer,bool sisExport = false): FilterDefinitionCollection {...public function getDealInsightsPageFilterSet(Criteria $criteria,User $consumer): FalterDefinitionCollection{..1 usagepubLic tunccion getleamAlAucomacionriltersetlSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:50+D ..CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepNow let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var ww nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuPo/ape/a/ports/ASkJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php —-no-coverage 2>&1"Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsperiod date filters1de handtes scalyr flttersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tilterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturnee o.Fix: AskJiminnyReportActivityService.php:51 —added 'sequence_number' → 1 to the Criteria: :createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that+ <> Code Claude Sonnet 4.6W Windsurf Teams11T:Z0uir-o( 4 spaces...
|
NULL
|
2271500362780084150
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v© ReportController.phpToolsWindowHelpyJiminnyDeouecommana.ongv Service© ActivityApiSearch.ph© ActivitySearch.php© UserOptionsByGrour© AbstractStageFilterDefilActivitySearchServicePrC DeallnsightsPeriodFilter0 DealinsidnisPeriodrilteng FilterDetinition.phpc rterverntoncolecto© FilterDefinitionQuery.ph© FilterDefinitionQueryCol• FilteredValueContainerli© IntMinMaxRange.php[ AiActivityType[ AiAutomationD AiCallScoringD AskAnythingD AskJiminnyAiDAWSM BillinaManagementM Cache• CoachingFeedback> D CountryD CustomerApi• DatabaseC DatadogC DateTimeDeallnsights_ DealRisksEasticsearch>_tloquent> DEncoding> D EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystemD GeckoD GongGuzzleHttpKeyPoints• KioskM LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot• MobileSettings| ModelNotiticationNudgeParagraphBreakerM ParticipantSpeechPartitionedCookieD PlaybackPagePlaylistTnesstatAulomaleakeporscommand.ono© AutomatedReportsSendCommand.phpAddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpsrono(e) TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Component\ActivitySearch\Service;© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 л› use ...class ActivitvSearch591141151161171181191201211124123lests passed: (a minute ago/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnIne column tc-oe* Oparam string $sortDirection The sort dire 107-108*orerurn coccecclonsauromceoreooro10912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/**114113114115116117* Retrieve all Ask Liminny reports created 2118* OodrdllusernusenThe user whos 119* @param string $sortColumnThe column tc 130* Oparam string $sortDirection The sort dire1151* Oreturn Collection<AutomatedReport>1Y114 usagespublic function getAskJiminnyReportsByUser(199User $user,-200string $sortColumn = 'created_at',string ssorcbirection = "desc"202): Collection {...}232253Z usages/**1254private function buildSortedQuery(string $sor235250237* Get all active and enabled reports with ac244245* @param string $frequency246247* dreturh coLcectzon<aucomacedкeрort>24825823 usagespublic function getActiveReportsByFrequency(:2597 usagesprivate Container $container;public function __construct(Container $container)f...}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function getOnDemandPageFilterSet(Criteria $criteria, User Sconsumer): FilterDefinitreturn $this->getOnDemandPageFilters()->nunenainchuerlay->withConsumer ($consumer)->withRestrictions($consumer->getTeam()):9 usagespublic function getArrayFilterKeys(User $consumer): arrayf..31 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,bool $includeDealType = false,bool $includePipeline = false,): FilterDefinitionCollection {.+public function getTeamInsightsPageFilterSet(cricerta pcracerta,user +consumer,bool sisExport = false): FilterDefinitionCollection {...public function getDealInsightsPageFilterSet(Criteria $criteria,User $consumer): FalterDefinitionCollection{..1 usagepubLic tunccion getleamAlAucomacionriltersetlSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:50+D ..CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepNow let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var ww nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuPo/ape/a/ports/ASkJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php —-no-coverage 2>&1"Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsperiod date filters1de handtes scalyr flttersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tilterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturnee o.Fix: AskJiminnyReportActivityService.php:51 —added 'sequence_number' → 1 to the Criteria: :createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that+ <> Code Claude Sonnet 4.6W Windsurf Teams11T:Z0uir-o( 4 spaces...
|
NULL
|
|
11068
|
219
|
24
|
2026-04-14T09:11:09.756710+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157869756_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v© ReportController.phpToolsWindowHelpyJiminnyDeouecommana.ongv Service© ActivityApiSearch.ph© ActivitySearch.php© UserOptionsByGrour© AbstractStageFilterDefilActivitySearchServicePrC DeallnsightsPeriodFilter0 Dealinsichisperiodrilterg FilterDetinition.phpc rterverntoncolecto© FilterDefinitionQuery.ph© FilterDefinitionQueryCol• FilteredValueContainerli© IntMinMaxRange.php[ AiActivityType[ AiAutomationD AiCallScoringD AskAnythingD AskJiminnyAiDAWSM BillinaManagementM Cache• CoachingFeedback> D CountryD CustomerApi• DatabaseC DatadogC DateTimeDeallnsights_ DealRisksEasticsearch>_tloquent> DEncoding> D EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystemD GeckoD GongGuzzleHttpKeyPoints• KioskM LanquageDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot• MobileSettings| ModelNotiticationNudgeParagraphBreakerM ParticipantSpeechPartitionedCookieD PlaybackPagePlaylistAulomaleakeporscommand.ono© AutomatedReportsSendCommand.phpAddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpsrono(e) TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Component\ActivitySearch\Service;© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php› use ...© AutomatedReportResult.phpclass ActivitvSearchclass Automacedкeрortskepo o:815 X4 л591141151161171181191201211124123Tests passed: 1 (2 minutes ago)/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnIne column tc-oe* Oparam string $sortDirection The sort dire 107* @return Collection<AutomatedReport>-10810912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/**114113114115116117* Retrieve all Ask Liminny reports created &118* OodrdllusernusenThe user whos 119* @param string $sortColumnThe column tc 130* Oparam string $sortDirection The sort dire1151* Oreturn Collection<AutomatedReport>1Y1*/14 usagespublic function getAskJiminnyReportsByUser(199User $user,-200string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}202232253Z usages/**1254private function buildSortedQuery(string $sor235250237* Get all active and enabled reports with ac244245* @param string $frequency246247* dreturh coLcectzon<aucomacedкeрort>24825823 usagespublic function getActiveReportsByFrequency(:2597 usagesprivate Container $container;public function __construct(Container $container){...}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function getOnDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()->nunenainchuerlay->withConsumer ($consumer)->withRestrictions($consumer->getTeam()):9 usagespublic function getArrayFilterkeys (User Sconsumer) : Errayt....1 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,bool $includeDealType = false,bool $includePipeline = false,): FilterDefinitionCollection {.+public function getTeamInsightsPageFilterSet(cricerta pcracerta,user +consumer,bool sisExport = false): FilterDefinitionCollection {...public function getDealInsightsPageFilterSet(Criteria $criteria,User $consumer): FalterDefinitionCollection1 usagepubLic tunccion getleamAlAucomacionriltersetl, 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:09CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -cSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest-php --no-coverage 2>61"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturnee oFix: AskJiminnyReportActivityService.php:51 —added 'sequence_number' → 1 to the Criteria: :createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetaccLeylasPassesNonzerosequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> Code Claude Sonnet 4.6W Windsurf Teams11T:Z0uir-o( 4 spaces...
|
NULL
|
-3979002410737055690
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v© ReportController.phpToolsWindowHelpyJiminnyDeouecommana.ongv Service© ActivityApiSearch.ph© ActivitySearch.php© UserOptionsByGrour© AbstractStageFilterDefilActivitySearchServicePrC DeallnsightsPeriodFilter0 Dealinsichisperiodrilterg FilterDetinition.phpc rterverntoncolecto© FilterDefinitionQuery.ph© FilterDefinitionQueryCol• FilteredValueContainerli© IntMinMaxRange.php[ AiActivityType[ AiAutomationD AiCallScoringD AskAnythingD AskJiminnyAiDAWSM BillinaManagementM Cache• CoachingFeedback> D CountryD CustomerApi• DatabaseC DatadogC DateTimeDeallnsights_ DealRisksEasticsearch>_tloquent> DEncoding> D EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystemD GeckoD GongGuzzleHttpKeyPoints• KioskM LanquageDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot• MobileSettings| ModelNotiticationNudgeParagraphBreakerM ParticipantSpeechPartitionedCookieD PlaybackPagePlaylistAulomaleakeporscommand.ono© AutomatedReportsSendCommand.phpAddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpsrono(e) TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Component\ActivitySearch\Service;© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php› use ...© AutomatedReportResult.phpclass ActivitvSearchclass Automacedкeрortskepo o:815 X4 л591141151161171181191201211124123Tests passed: 1 (2 minutes ago)/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnIne column tc-oe* Oparam string $sortDirection The sort dire 107* @return Collection<AutomatedReport>-10810912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/**114113114115116117* Retrieve all Ask Liminny reports created &118* OodrdllusernusenThe user whos 119* @param string $sortColumnThe column tc 130* Oparam string $sortDirection The sort dire1151* Oreturn Collection<AutomatedReport>1Y1*/14 usagespublic function getAskJiminnyReportsByUser(199User $user,-200string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}202232253Z usages/**1254private function buildSortedQuery(string $sor235250237* Get all active and enabled reports with ac244245* @param string $frequency246247* dreturh coLcectzon<aucomacedкeрort>24825823 usagespublic function getActiveReportsByFrequency(:2597 usagesprivate Container $container;public function __construct(Container $container){...}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function getOnDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()->nunenainchuerlay->withConsumer ($consumer)->withRestrictions($consumer->getTeam()):9 usagespublic function getArrayFilterkeys (User Sconsumer) : Errayt....1 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,bool $includeDealType = false,bool $includePipeline = false,): FilterDefinitionCollection {.+public function getTeamInsightsPageFilterSet(cricerta pcracerta,user +consumer,bool sisExport = false): FilterDefinitionCollection {...public function getDealInsightsPageFilterSet(Criteria $criteria,User $consumer): FalterDefinitionCollection1 usagepubLic tunccion getleamAlAucomacionriltersetl, 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:09CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -cSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest-php --no-coverage 2>61"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturnee oFix: AskJiminnyReportActivityService.php:51 —added 'sequence_number' → 1 to the Criteria: :createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetaccLeylasPassesNonzerosequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> Code Claude Sonnet 4.6W Windsurf Teams11T:Z0uir-o( 4 spaces...
|
11066
|
|
11069
|
219
|
25
|
2026-04-14T09:11:12.113138+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157872113_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp, 0lablj Support Daily • in 2h 49 mA100% |45]Tue 14 Apr 12:11:11FV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vAskJiminnyReportActivityServiceT…DefaultsProject v© ReportController.phpyJiminnyDeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]Cascadev ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php xFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.phpAddLayoutEntities.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpNow let's run the test to verifv© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php XRequestGenerateAskJiminnyReportJobTest.php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrsronoCommand dockenwC DeallnsightsPeriodFilter(e TrackProvidernstallled-vent.onodeclare(strict_types=1);o desker nxe dovkcrs/ko3k Automwa/wprts/art1nan yReportActivityserviceTest-php --no-coverage0 DealinsidnisPeriodrilten© CreateActivityLoggedEvent.php© UserPilotActivityListener.phploul nor oen ndlr Tler var wi nunbarusang FilterDetinition.php(©) ActivityLogged.phpnamespace Jiminny\Component\ActivitySearch\Service;) Aulomaleakeporscallbackservice.onoc rterverntoncolectoCommand dockel© FilterDefinitionQuery.ph© RequestGenerateAskJiminnyReportJob.php› use ...© FilterDefinitionQueryColA Naalinn auna daalian lama 1 abaRequestGenerateReportJob.php© AutomatedReportResult.phpassesllesSymbolsActionsextProiect HllesvTiminnyReportActivityServiceTest.php --no-coverage• FilteredValueContainerliclass ActivitvSearch© IntMinMaxRange.php(C) AutomatedReport.phpQ- OnDemal[ AiActivityTypeclass Automacedкeрortskepo o:815 X4 л7 usages[ AiAutomationprivate Container $container;DOnDemandActivitySearch app/VO/Repository/OnDemandActivitySearchD AiCallScoring© OnDemandController.php•aoo nuo controlers Ariraee unvemanacontroler.ono&& php artisan testJiminnyReportActivityServiceTest.php --no-coverage 2>&1"D AskAnythingpublic function __construct(Container $container)f.© OnDemandActivitiesTransformer.php .../app/Http/Transformers/OnDemandActivitiesTransformer.phpD AskJiminnyAi* Retrieve all standard (non-Ask Jiminny) M• OnDemandLevel app/Component/AskJiminnyAi/OnDemandLevelDAWSpublic function get0nDemandPageFilters(): FilterDefir© OnDemandAskAnythingRequest.php .../app/Http/Requests/API/V2/OnDemandAskAnythingRequest.pM BillinaManagement59* @param string $sortColumnIne column tc-oe© OnDemandV2Controller.php.../app/Http/Controllers/API/V2/OnDemandV2Controller.phpM Cache* Oparam string $sortDirection The sort dire 107public function getOnDemandPageFilterSet(Criteria $crOnDemandActivitySearch build/coverage/VO/Repository/OnDemandActivitySearche artisan -maxdeoth 6 2>/dev/null | head -5"• CoachingFeedback_108OnDemandV2ControllerTest.php .../tests/Unit/Http/Controllers/Api/V2/OnDemandV2ControllerTest.p> D Country*orerurn coccecclonsauromceoreooro109return $this<> OnDemandController.php.html build/coverage/Http/Controllers/APl/PageD CustomerApi• Database->getOnDemandPageFilters()‹/ OnvemanoAcrvrescnstommerono.numi oullc/covercerruoanstommers12 usages111-›withCriteria($criteria)<> OndemandController.php.html build/coverage/Http/ControllersC Datadogpublic function getAllStandardReports(112->withConsumer($consumer)ninny && php artisan testJiminnyReportActivityServiceTest-php --no-coverage 2>&1"C DateTimestring $sortColumn = 'created_at',Deallnsights113->withRestrictions($consumer->getTeam()):string $sortDirection = 'desc'114_ DealRisksEasticsearch): Collection {...J115poy wen n resporatet ipamtereseempty when no results116 F>_tloquent> DEncoding/**1171 date filters* Retrieve all Ask Liminny reports created f118number to disable first r... 0.03s> D Encryption9 usagesDES* OodrdllusernusenThe user whos 119public function getArrayFilterKeys(User $consumer): aD Faker* @param string $sortColumnThe column tc 130• FeatureFlags* Oparam string $sortDirection The sort dire1 usageD FFMpeg1151private function getTeamInsightsPageFilters(bool $isEsence number in the request params, so criceria:: creater romkequest deraultea itlo 0• FileSystem- === 0, several implicit defaults were silently applied:* Oreturn Collection<AutomatedReport>1Y1D Geckoto-second acrivitiesD Gong14 usagesprivate function getDealInsightsPageFilters(corded activities only)GuzzleHttppublic function getAskJiminnyReportsByUser(199bool $useCreatedDate = false,KeyPointsUser $user,-200bool $includeDealType = false,• Kioskch disables these defaults - explaining why the frontend returned activities but the servicestring $sortColumn = 'created_at',bool $includePipeline = false,M LanquadeDetectionstring ssorcbirection = "desc"202): FilterDefinitionCollection {.+LiveFeed): Collection {...J232sequence_number' → 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequevukepositoryonbemaneAcuivilysearchOpen In Right SplitD Locks253public function getTeamInsightsPageFilterSet(lestadded: testoetAculvlcyLaspassesnonzerosequencenumberlob1sablerursckequestberau Lus asserts that the captured urlterla oblect nas 1shirs• MathZ usages1254cricerta pcracerta,tRequest() === false.• MediaPipelineprivate function buildSortedQuery(string $sor235user +consumer,Oul .• MeetingBot114250bool sisExport = false• MobileSettings115/**237): FilterDefinitionCollection {..| ModelNotitication116* Get all active and enabled reports with ac 244117Nudge245public function getDealInsightsPageFilterSet(118* @param string $frequency246Criteria $criteria,Vew allliParagraphBreakerItlle wiun changesv119247User $consumerapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1M ParticipantSpeech120* dreturn cocLectron<Aucomacedкeрort»248): Falterbefinitioncollection i...rReject allAccept allPartitionedCookie121D PlaybackPage258Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used ir23 usages1 usagePlaylist1124public function getActiveReportsByFrequency(:259pubLic tuncclon getleamA1AutomationFilterSet(123+ <> Code Claude Sonnet 4.6Tests passed: 1 (2 minutes ago)winasun leams118.duir-o( 4 spaces...
|
NULL
|
4475248259659255375
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp, 0lablj Support Daily • in 2h 49 mA100% |45]Tue 14 Apr 12:11:11FV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vAskJiminnyReportActivityServiceT…DefaultsProject v© ReportController.phpyJiminnyDeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]Cascadev ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php xFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.phpAddLayoutEntities.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpNow let's run the test to verifv© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php XRequestGenerateAskJiminnyReportJobTest.php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrsronoCommand dockenwC DeallnsightsPeriodFilter(e TrackProvidernstallled-vent.onodeclare(strict_types=1);o desker nxe dovkcrs/ko3k Automwa/wprts/art1nan yReportActivityserviceTest-php --no-coverage0 DealinsidnisPeriodrilten© CreateActivityLoggedEvent.php© UserPilotActivityListener.phploul nor oen ndlr Tler var wi nunbarusang FilterDetinition.php(©) ActivityLogged.phpnamespace Jiminny\Component\ActivitySearch\Service;) Aulomaleakeporscallbackservice.onoc rterverntoncolectoCommand dockel© FilterDefinitionQuery.ph© RequestGenerateAskJiminnyReportJob.php› use ...© FilterDefinitionQueryColA Naalinn auna daalian lama 1 abaRequestGenerateReportJob.php© AutomatedReportResult.phpassesllesSymbolsActionsextProiect HllesvTiminnyReportActivityServiceTest.php --no-coverage• FilteredValueContainerliclass ActivitvSearch© IntMinMaxRange.php(C) AutomatedReport.phpQ- OnDemal[ AiActivityTypeclass Automacedкeрortskepo o:815 X4 л7 usages[ AiAutomationprivate Container $container;DOnDemandActivitySearch app/VO/Repository/OnDemandActivitySearchD AiCallScoring© OnDemandController.php•aoo nuo controlers Ariraee unvemanacontroler.ono&& php artisan testJiminnyReportActivityServiceTest.php --no-coverage 2>&1"D AskAnythingpublic function __construct(Container $container)f.© OnDemandActivitiesTransformer.php .../app/Http/Transformers/OnDemandActivitiesTransformer.phpD AskJiminnyAi* Retrieve all standard (non-Ask Jiminny) M• OnDemandLevel app/Component/AskJiminnyAi/OnDemandLevelDAWSpublic function get0nDemandPageFilters(): FilterDefir© OnDemandAskAnythingRequest.php .../app/Http/Requests/API/V2/OnDemandAskAnythingRequest.pM BillinaManagement59* @param string $sortColumnIne column tc-oe© OnDemandV2Controller.php.../app/Http/Controllers/API/V2/OnDemandV2Controller.phpM Cache* Oparam string $sortDirection The sort dire 107public function getOnDemandPageFilterSet(Criteria $crOnDemandActivitySearch build/coverage/VO/Repository/OnDemandActivitySearche artisan -maxdeoth 6 2>/dev/null | head -5"• CoachingFeedback_108OnDemandV2ControllerTest.php .../tests/Unit/Http/Controllers/Api/V2/OnDemandV2ControllerTest.p> D Country*orerurn coccecclonsauromceoreooro109return $this<> OnDemandController.php.html build/coverage/Http/Controllers/APl/PageD CustomerApi• Database->getOnDemandPageFilters()‹/ OnvemanoAcrvrescnstommerono.numi oullc/covercerruoanstommers12 usages111-›withCriteria($criteria)<> OndemandController.php.html build/coverage/Http/ControllersC Datadogpublic function getAllStandardReports(112->withConsumer($consumer)ninny && php artisan testJiminnyReportActivityServiceTest-php --no-coverage 2>&1"C DateTimestring $sortColumn = 'created_at',Deallnsights113->withRestrictions($consumer->getTeam()):string $sortDirection = 'desc'114_ DealRisksEasticsearch): Collection {...J115poy wen n resporatet ipamtereseempty when no results116 F>_tloquent> DEncoding/**1171 date filters* Retrieve all Ask Liminny reports created f118number to disable first r... 0.03s> D Encryption9 usagesDES* OodrdllusernusenThe user whos 119public function getArrayFilterKeys(User $consumer): aD Faker* @param string $sortColumnThe column tc 130• FeatureFlags* Oparam string $sortDirection The sort dire1 usageD FFMpeg1151private function getTeamInsightsPageFilters(bool $isEsence number in the request params, so criceria:: creater romkequest deraultea itlo 0• FileSystem- === 0, several implicit defaults were silently applied:* Oreturn Collection<AutomatedReport>1Y1D Geckoto-second acrivitiesD Gong14 usagesprivate function getDealInsightsPageFilters(corded activities only)GuzzleHttppublic function getAskJiminnyReportsByUser(199bool $useCreatedDate = false,KeyPointsUser $user,-200bool $includeDealType = false,• Kioskch disables these defaults - explaining why the frontend returned activities but the servicestring $sortColumn = 'created_at',bool $includePipeline = false,M LanquadeDetectionstring ssorcbirection = "desc"202): FilterDefinitionCollection {.+LiveFeed): Collection {...J232sequence_number' → 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequevukepositoryonbemaneAcuivilysearchOpen In Right SplitD Locks253public function getTeamInsightsPageFilterSet(lestadded: testoetAculvlcyLaspassesnonzerosequencenumberlob1sablerursckequestberau Lus asserts that the captured urlterla oblect nas 1shirs• MathZ usages1254cricerta pcracerta,tRequest() === false.• MediaPipelineprivate function buildSortedQuery(string $sor235user +consumer,Oul .• MeetingBot114250bool sisExport = false• MobileSettings115/**237): FilterDefinitionCollection {..| ModelNotitication116* Get all active and enabled reports with ac 244117Nudge245public function getDealInsightsPageFilterSet(118* @param string $frequency246Criteria $criteria,Vew allliParagraphBreakerItlle wiun changesv119247User $consumerapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1M ParticipantSpeech120* dreturn cocLectron<Aucomacedкeрort»248): Falterbefinitioncollection i...rReject allAccept allPartitionedCookie121D PlaybackPage258Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used ir23 usages1 usagePlaylist1124public function getActiveReportsByFrequency(:259pubLic tuncclon getleamA1AutomationFilterSet(123+ <> Code Claude Sonnet 4.6Tests passed: 1 (2 minutes ago)winasun leams118.duir-o( 4 spaces...
|
NULL
|
|
11070
|
219
|
26
|
2026-04-14T09:11:18.145849+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157878145_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl, folder
ActionItems, folder
Activity, folder
ActivityAnalytics, folder
ActivitySearch, folder
EventSubscriber, folder
FilterDefinition, folder
Service
ActivityApiSearch.php, class
ActivitySearch.php, class
UserOptionsByGroup.php, class
AbstractStageFilterDefinition.php, abstract class
ActivitySearchServiceProvider.php, final class
DealInsightsPeriodFilterFactory.php
DealInsightsPeriodFilterFactoryInterface.php, interface
FilterDefinition.php, abstract class
FilterDefinitionCollection.php, class
FilterDefinitionQuery.php, class
FilterDefinitionQueryCollection.php, class
FilteredValueContainerInterface.php, interface
IntMinMaxRange.php, class
AiActivityType
AiAutomation
AiCallScoring
AskAnything
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model
Notification
Nudge
ParagraphBreaker
ParticipantSpeech
PartitionedCookie
PlaybackPage
Playlist
Prophet
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.57539064,"top":0.13055556,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.58632815,"top":0.13055556,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.59765625,"top":0.12916666,"width":0.00859375,"height":0.015972223},"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.60625,"top":0.12916666,"width":0.008203125,"height":0.015972223},"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\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"EventSubscriber, folder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinition, folder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Service","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityApiSearch.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UserOptionsByGroup.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AbstractStageFilterDefinition.php, abstract class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearchServiceProvider.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsPeriodFilterFactory.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsPeriodFilterFactoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinition.php, abstract class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionCollection.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionQuery.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionQueryCollection.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilteredValueContainerInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"IntMinMaxRange.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playlists","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Postmark","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Reports","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"role_description":"text"}]...
|
-1792450594297658947
|
-5824280404149933980
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl, folder
ActionItems, folder
Activity, folder
ActivityAnalytics, folder
ActivitySearch, folder
EventSubscriber, folder
FilterDefinition, folder
Service
ActivityApiSearch.php, class
ActivitySearch.php, class
UserOptionsByGroup.php, class
AbstractStageFilterDefinition.php, abstract class
ActivitySearchServiceProvider.php, final class
DealInsightsPeriodFilterFactory.php
DealInsightsPeriodFilterFactoryInterface.php, interface
FilterDefinition.php, abstract class
FilterDefinitionCollection.php, class
FilterDefinitionQuery.php, class
FilterDefinitionQueryCollection.php, class
FilteredValueContainerInterface.php, interface
IntMinMaxRange.php, class
AiActivityType
AiAutomation
AiCallScoring
AskAnything
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model
Notification
Nudge
ParagraphBreaker
ParticipantSpeech
PartitionedCookie
PlaybackPage
Playlist
Prophet
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class...
|
11069
|
|
11072
|
219
|
27
|
2026-04-14T09:11:23.735535+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157883735_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-304832669432165688
|
-8852932249833634878
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v© ReportController.phpJiminnybeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 49 mA100% C•Tue 14 Apr 12:11:23AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php(C) PropagateCoachingFee© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (2 minutes ago)= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.pnpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:B15 X4 AOnDemandV2Controller.php x© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller47public function_construct(opnetservice spropnetservicemAiContextRepository $teamAiContextRepository,FiveStreamsRepository $activeStreamsRepository,intDispatcher $eventDispatcher,igerInterface $logger,Now let's run the test to verify41 M2 ^wtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanealn nos wne hox suiN oN Any rimo reccure endotee61931141151161171181191211124123/**> ikJiminnyOnAnythingFeature(User $user): ?JsonResponsef...}Command dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan* Retrieve all standard (non-Ask Jiminny) Mis for Ask Jiminny feature based on filters* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulreCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan* @return Collection<AutomatedReport>ceptioniderException12 usages78 Qg › :xtForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonRespons."cd /homee/jiminny && php artisan testpublic function getAllStandardReports(tests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"string $sortColumn = 'created_at',PASSstring $sortDirection = 'desc'127): Collection {...J› igedContextFilter(Request $request, User $user): boolf...}getTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTest157filtersemoty when no results/*** Retrieve all Ask Liminny reports created› _terKey(Request $request): string{...}E tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025* Oodrdll usernusenIne user YnosAll 8 tests pass. Here's a summary:* @param string $sortColumnThe column to* Oparam string $sortDirection The sort direversation historyRoot Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0* @return Collection<AutomatedReport>Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:184 Qg › lythingHistory(Request $request): JsonResponse{...}*/Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesi-20814 usagesActivityRecorded → only_recorded = 1 (restricts to recorded activities only)209public function getAskJiminnyReportsByUser(OrganiserGroupIn → applies user's default group as a filtel-210conversation historyUser $user,211The frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicestring $sortColumn = 'created_at',returned O.string ssorcbirection = "desc"Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstReque): Collection {...J212 (Q › ikAnythingHistory(Request $request): JsonResponsef...}st() returns false and no implicit defaults are injected.237Test added: testGetActLeylasPassesNonzerosequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirs— 238tRequest () === false.2 usagesprivate function buildSortedQuery(string $sor239question and aet AT responseÖul ../*** Get all active and enabled reports with a<349241 (g> láng(OnDemandASKAnythingRequest Srequest): StreamedResponselJsonResponse(... 3* @param string $frequencyVew allli350 (g > tam(Request $request): JsonResponse{...}Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1-364* dreturn cocLectron<Aucomacedкeрort»Reject allAccept all365Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in23 usagespublic function getActiveReportsByFrequency(s+ <> Code Claude Sonnet 4.6Winasun leamsuir-o( 4 spaces...
|
NULL
|
|
11074
|
219
|
28
|
2026-04-14T09:11:29.958882+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157889958_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny k vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.ono(e TrackProvidernstallled-vent.onoOnDemandV2Controller.php >© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpcPoquoctcenerateask.iminnvreoorJoolestongclass OnDemandV2Controller extends ControllerA1 X2 лpublic function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResp=nrequest-ousero.© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 A v 2522411244245246247248249250251253254616275931141151161171181191211124123/*** Retrieve all standard (non-Ask Limiony) e256* @param string $sortColumnThe column t 258* @param string $sortDirection The sort dire259260$requestData = [* @return Collection<AutomatedReport>*/262vstqus 3o Stms -Shistorya vase-sge teontexezds (suser,identifier: HistoryServic12 usages263identifier: HistoryService:public function getAllStandardReports(264]:'history' => $this->historyService->getHistory($user,265string $sortColumn = 'created_at',string $sortDirection = 'desc'266): Collection {..+267268фteamAlcontext = schis->ceamAlconcexckeposicory-›getbyleamta(puser->getleamtaiif ($teamAiContext?->getPrompt( !== null) {$requestData['teamAiContext'] = $teamAiContext->getPrompt();/**269* Retrieve all Ask Liminny reports created* Oodrdll usernusenIne user Ynos272* @param string $sortColumnThe column t,273* Oparam string $sortDirection The sort dire274275* @return Collection<AutomatedReport>276277*/- 27814 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J282283284— 285Z usagesprivate function buildSortedQuery(string $sor286- 288/*** Get all active and enabled reports with ac 289291* @param string $frequency292-293* dreturn cocLectron<Aucomacedкeрort»29423 usages295public function getActiveReportsByFrequency(s296297$this->logger->info('AskAnything request received', ['user_id' => $user-›getId(),'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') .$user->getId() . flor'message_preview' →> mb_substr($request->input( key: 'message'), 0, 50),I);if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return steacureuneckitry &$inputData = $request->validated():$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']nunus-onscorvservce-›aooeno o-venchistorvuuuser. nuseraoenmer. scorvoeru Cer.UN UEMAND OCKuILCtype: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),tseconos: oscreankedves-›cerconnectmeour + screankequest-›cetreadimeoureturn $this->prophetService->getStreamed0rAbortedResponse(streamRequest: $streamRequest,onCompleted: function (string $assistantResponse,bool $clientAborted,Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:29CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifywtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker lano oasn —c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ ‹> CodeClaude Sonnet 4.6W Windsurf Teams241:100uir-o( 4 spaces...
|
NULL
|
1120266126392271691
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny k vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.ono(e TrackProvidernstallled-vent.onoOnDemandV2Controller.php >© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpcPoquoctcenerateask.iminnvreoorJoolestongclass OnDemandV2Controller extends ControllerA1 X2 лpublic function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResp=nrequest-ousero.© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 A v 2522411244245246247248249250251253254616275931141151161171181191211124123/*** Retrieve all standard (non-Ask Limiony) e256* @param string $sortColumnThe column t 258* @param string $sortDirection The sort dire259260$requestData = [* @return Collection<AutomatedReport>*/262vstqus 3o Stms -Shistorya vase-sge teontexezds (suser,identifier: HistoryServic12 usages263identifier: HistoryService:public function getAllStandardReports(264]:'history' => $this->historyService->getHistory($user,265string $sortColumn = 'created_at',string $sortDirection = 'desc'266): Collection {..+267268фteamAlcontext = schis->ceamAlconcexckeposicory-›getbyleamta(puser->getleamtaiif ($teamAiContext?->getPrompt( !== null) {$requestData['teamAiContext'] = $teamAiContext->getPrompt();/**269* Retrieve all Ask Liminny reports created* Oodrdll usernusenIne user Ynos272* @param string $sortColumnThe column t,273* Oparam string $sortDirection The sort dire274275* @return Collection<AutomatedReport>276277*/- 27814 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J282283284— 285Z usagesprivate function buildSortedQuery(string $sor286- 288/*** Get all active and enabled reports with ac 289291* @param string $frequency292-293* dreturn cocLectron<Aucomacedкeрort»29423 usages295public function getActiveReportsByFrequency(s296297$this->logger->info('AskAnything request received', ['user_id' => $user-›getId(),'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') .$user->getId() . flor'message_preview' →> mb_substr($request->input( key: 'message'), 0, 50),I);if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return steacureuneckitry &$inputData = $request->validated():$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']nunus-onscorvservce-›aooeno o-venchistorvuuuser. nuseraoenmer. scorvoeru Cer.UN UEMAND OCKuILCtype: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),tseconos: oscreankedves-›cerconnectmeour + screankequest-›cetreadimeoureturn $this->prophetService->getStreamed0rAbortedResponse(streamRequest: $streamRequest,onCompleted: function (string $assistantResponse,bool $clientAborted,Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:29CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifywtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker lano oasn —c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ ‹> CodeClaude Sonnet 4.6W Windsurf Teams241:100uir-o( 4 spaces...
|
11072
|
|
11076
|
219
|
29
|
2026-04-14T09:11:32.240518+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157892240_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.ono(e) TrackProvidernstallled-vent.onoOnDemandV2Controller.php >© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpcPequectcenerateask.iminnvreoorJoolestongclass OnDemandV2Controller extends ControllerA1 X2 лpublic function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp=nrequest-ousero.© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 A v 2522411244245246247248249250251253254616275931141151161171181191211124123/*** Retrieve all standard (non-ASk Limiony) e256* @param string $sortColumnThe column t 258* @param string $sortDirection The sort dire259260$requestData = [* @return Collection<AutomatedReport>'userQuestion' => $inputData[ 'message'],*/262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic12 usages263identifier: HistoryService:public function getAllStandardReports(264]:'history' => $this->historyService->getHistory($user,265string $sortColumn = 'created_at',string $sortDirection = 'desc'266): Collection {..+267268фteamAlcontext = schis->ceamAlconcexckeposicory-›getbyleamta(puser->getleamta:if ($teamAiContext?->getPrompt( !== null) {$requestData['teamAiContext'] = $teamAiContext->getPrompt();/**269* Retrieve all Ask Liminny reports created* Oodrdll usernusenIne user Ynos272* @param string $sortColumnThe column t,273* Oparam string $sortDirection The sort dire274275276* @return Collection<AutomatedReport>277*/-27814 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J282283— 285Z usagesprivate function buildSortedQuery(string $sor286- 288/*** Get all active and enabled reports with ac 289291* @param string $frequency292-293* dreturh coLcectzon<aucomacedкeрort>29423 usages295public function getActiveReportsByFrequency(s296297$this->logger->info('AskAnything request received', ['user_id' => $user-›getId(),'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') .$user->getId() . flor'message_preview' →> mb_substr($request->input( key: 'message'), 0, 50),I);if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return steacureuneckitry &$inputData = $request->validated():$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']$this->historyService->appendToEventHistory(user: $user,identifien: HistoryService: :ON_DEPAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ruseconos. screankedves-›cerconnectmeour + screankequest-›cetreadiameoureturn $this->prophetService->getStreamed0rAbortedResponse(streamRequest: $streamRequest,onCompleted: function (string $assistantResponse,bool $clientAborted,Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:31CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker lano oasn —"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> CodeClaude Sonnet 4.6Winasun leams203:05uir-o( 4 spaces...
|
NULL
|
-6243280995640528695
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.ono(e) TrackProvidernstallled-vent.onoOnDemandV2Controller.php >© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpcPequectcenerateask.iminnvreoorJoolestongclass OnDemandV2Controller extends ControllerA1 X2 лpublic function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp=nrequest-ousero.© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 A v 2522411244245246247248249250251253254616275931141151161171181191211124123/*** Retrieve all standard (non-ASk Limiony) e256* @param string $sortColumnThe column t 258* @param string $sortDirection The sort dire259260$requestData = [* @return Collection<AutomatedReport>'userQuestion' => $inputData[ 'message'],*/262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic12 usages263identifier: HistoryService:public function getAllStandardReports(264]:'history' => $this->historyService->getHistory($user,265string $sortColumn = 'created_at',string $sortDirection = 'desc'266): Collection {..+267268фteamAlcontext = schis->ceamAlconcexckeposicory-›getbyleamta(puser->getleamta:if ($teamAiContext?->getPrompt( !== null) {$requestData['teamAiContext'] = $teamAiContext->getPrompt();/**269* Retrieve all Ask Liminny reports created* Oodrdll usernusenIne user Ynos272* @param string $sortColumnThe column t,273* Oparam string $sortDirection The sort dire274275276* @return Collection<AutomatedReport>277*/-27814 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J282283— 285Z usagesprivate function buildSortedQuery(string $sor286- 288/*** Get all active and enabled reports with ac 289291* @param string $frequency292-293* dreturh coLcectzon<aucomacedкeрort>29423 usages295public function getActiveReportsByFrequency(s296297$this->logger->info('AskAnything request received', ['user_id' => $user-›getId(),'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') .$user->getId() . flor'message_preview' →> mb_substr($request->input( key: 'message'), 0, 50),I);if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return steacureuneckitry &$inputData = $request->validated():$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']$this->historyService->appendToEventHistory(user: $user,identifien: HistoryService: :ON_DEPAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ruseconos. screankedves-›cerconnectmeour + screankequest-›cetreadiameoureturn $this->prophetService->getStreamed0rAbortedResponse(streamRequest: $streamRequest,onCompleted: function (string $assistantResponse,bool $clientAborted,Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:31CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker lano oasn —"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> CodeClaude Sonnet 4.6Winasun leams203:05uir-o( 4 spaces...
|
NULL
|
|
11079
|
219
|
30
|
2026-04-14T09:11:34.900696+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157894900_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.ono(e) TrackProvidernstallled-vent.onoOnDemandV2Controller.php >© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpcPequectcenerateask.iminnvreoorJoolestongclass OnDemandV2Controller extends ControllerA1 X2 лpublic function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResp=nrequest-ousero.© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 A v 2522411244245246247248249250251253254616275931141151161171181191211124123/*** Retrieve all standard (non-ASk Limiony) e256* @param string $sortColumnThe column t 258* @param string $sortDirection The sort dire259260$requestData = [* @return Collection<AutomatedReport>'userQuestion' => $inputData[ 'message'],*/262'callIds' => $this->historyService->getContextIds($user,identifer: HistoryServic12 usages263identifier: HistoryService:public function getAllStandardReports(264]:'history' => $this->historyService->getHistory($user,265string $sortColumn = 'created_at',string $sortDirection = 'desc'266): Collection {..+267268фteamAlcontext = schis->ceamAlconcexckeposicory-›getbyleamta(puser-›getleamta:if ($teamAiContext?->getPrompt( !== null) {$requestData['teamAiContext'] = $teamAiContext->getPrompt();/**269* Retrieve all Ask Liminny reports created* Oodrdll usernusenIne user Ynos272* @param string $sortColumnThe column t,273* Oparam string $sortDirection The sort dire274275* @return Collection<AutomatedReport>276277*/- 27814 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J281282283284— 285Z usagesprivate function buildSortedQuery(string $sor286- 288/*** Get all active and enabled reports with ac 289291* @param string $frequency292-293* dreturh coLcectzon<aucomacedкeрort>29423 usages295public function getActiveReportsByFrequency(s296297$this->logger->info('AskAnything request received', ['user_id' => $user-›getId(),'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') .$user->getId() . flor'message_preview' →> mb_substr($request->input( key: 'message'), 0, 50),I);if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return steacureuneckitry &$inputData = $request->validated():$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::ON_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ruseconos. screankedves-›cerconnectmeour + screankequest-›cetreadiameou):return $this->prophetService->getStreamed0rAbortedResponse(streamRequest: $streamRequest,onCompleted: function (string $assistantResponse,bool $clientAborted,Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:34CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen tndlr Tler var ww nunwarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdenth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetaccLeylasPassesNonzerosequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> CodeClaude Sonnet 4.6Winasun leams292:0/uir-o( 4 spaces...
|
NULL
|
-3596243169602343275
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.ono(e) TrackProvidernstallled-vent.onoOnDemandV2Controller.php >© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpcPequectcenerateask.iminnvreoorJoolestongclass OnDemandV2Controller extends ControllerA1 X2 лpublic function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResp=nrequest-ousero.© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 A v 2522411244245246247248249250251253254616275931141151161171181191211124123/*** Retrieve all standard (non-ASk Limiony) e256* @param string $sortColumnThe column t 258* @param string $sortDirection The sort dire259260$requestData = [* @return Collection<AutomatedReport>'userQuestion' => $inputData[ 'message'],*/262'callIds' => $this->historyService->getContextIds($user,identifer: HistoryServic12 usages263identifier: HistoryService:public function getAllStandardReports(264]:'history' => $this->historyService->getHistory($user,265string $sortColumn = 'created_at',string $sortDirection = 'desc'266): Collection {..+267268фteamAlcontext = schis->ceamAlconcexckeposicory-›getbyleamta(puser-›getleamta:if ($teamAiContext?->getPrompt( !== null) {$requestData['teamAiContext'] = $teamAiContext->getPrompt();/**269* Retrieve all Ask Liminny reports created* Oodrdll usernusenIne user Ynos272* @param string $sortColumnThe column t,273* Oparam string $sortDirection The sort dire274275* @return Collection<AutomatedReport>276277*/- 27814 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J281282283284— 285Z usagesprivate function buildSortedQuery(string $sor286- 288/*** Get all active and enabled reports with ac 289291* @param string $frequency292-293* dreturh coLcectzon<aucomacedкeрort>29423 usages295public function getActiveReportsByFrequency(s296297$this->logger->info('AskAnything request received', ['user_id' => $user-›getId(),'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') .$user->getId() . flor'message_preview' →> mb_substr($request->input( key: 'message'), 0, 50),I);if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return steacureuneckitry &$inputData = $request->validated():$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::ON_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ruseconos. screankedves-›cerconnectmeour + screankequest-›cetreadiameou):return $this->prophetService->getStreamed0rAbortedResponse(streamRequest: $streamRequest,onCompleted: function (string $assistantResponse,bool $clientAborted,Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:34CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen tndlr Tler var ww nunwarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdenth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetaccLeylasPassesNonzerosequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> CodeClaude Sonnet 4.6Winasun leams292:0/uir-o( 4 spaces...
|
11076
|
|
11082
|
219
|
31
|
2026-04-14T09:11:37.939136+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157897939_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrorenvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (2 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.ono(e TrackProvidernstallled-vent.onoOnDemandV2Controller.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpcPequectcenerateask.iminnvreoorJoolestongclass OnDemandV2Controller extends ControllerA1 X2 лpublic function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResp=nrequest-ousero.© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 A v 2522411244245246247248249250251253254616275931141151161171181191211124123/*** Retrieve all standard (non-ASk Limiony) e256* @param string $sortColumnThe column t 258* @param string $sortDirection The sort dire259260$requestData = [* @return Collection<AutomatedReport>'userQuestion' => $inputData[ 'message'],*/262'callIds' => $this->historyService->getContextIds($user,identifer: HistoryServic12 usages263'history' = $this->historyService->getHistory(Suserdidentifier: HistoryService:public function getAllStandardReports(264]:265string $sortColumn = 'created_at',string $sortDirection = 'desc'266): Collection {..+267268фteamAlcontext = schis->ceamAlconcexckeposicory-›getbyleamta(puser->getleamta:if ($teamAiContext?->getPrompt( !== null) {$requestData['teamAiContext'] = $teamAiContext->getPrompt();/**269* Retrieve all Ask Liminny reports created* Oodrdll usernusenIne user Ynos272* @param string $sortColumnThe column t,273* Oparam string $sortDirection The sort dire274275276* @return Collection<AutomatedReport>277*/-27814 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J282283— 285Z usagesprivate function buildSortedQuery(string $sor286- 288/*** Get all active and enabled reports with ac 289291* @param string $frequency292-293* dreturn cocLectron<Aucomacedкeрort»29423 usages295public function getActiveReportsByFrequency(s296297$this->logger->info('AskAnything request received', ['user_id' => $user-›getId(),'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') .$user->getId() . flor'message_preview' →> mb_substr($request->input( key: 'message'), 0, 50),I);if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return steacureuneckitry &$inputData = $request->validated():$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,oenmer. scorvoeru Cer.UN UEMAND OCKuILCtype: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemondLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ruseconos. screankedves-›cerconnectmeour + screankequest-›cetreadiameoureturn $this->prophetService->getStreamed0rAbortedResponse(streamRequest: $streamRequest,onCompleted: function (string $assistantResponse,bool $clientAborted,, 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:37CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest,php --no-coverage 261"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersget activity ids hassees sn zero sequence number to disable first r._ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> CodeClaude Sonnet 4.6winasun leams203:0uir-o( 4 spaces...
|
NULL
|
8196210200034818658
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrorenvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (2 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.ono(e TrackProvidernstallled-vent.onoOnDemandV2Controller.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpcPequectcenerateask.iminnvreoorJoolestongclass OnDemandV2Controller extends ControllerA1 X2 лpublic function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResp=nrequest-ousero.© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 A v 2522411244245246247248249250251253254616275931141151161171181191211124123/*** Retrieve all standard (non-ASk Limiony) e256* @param string $sortColumnThe column t 258* @param string $sortDirection The sort dire259260$requestData = [* @return Collection<AutomatedReport>'userQuestion' => $inputData[ 'message'],*/262'callIds' => $this->historyService->getContextIds($user,identifer: HistoryServic12 usages263'history' = $this->historyService->getHistory(Suserdidentifier: HistoryService:public function getAllStandardReports(264]:265string $sortColumn = 'created_at',string $sortDirection = 'desc'266): Collection {..+267268фteamAlcontext = schis->ceamAlconcexckeposicory-›getbyleamta(puser->getleamta:if ($teamAiContext?->getPrompt( !== null) {$requestData['teamAiContext'] = $teamAiContext->getPrompt();/**269* Retrieve all Ask Liminny reports created* Oodrdll usernusenIne user Ynos272* @param string $sortColumnThe column t,273* Oparam string $sortDirection The sort dire274275276* @return Collection<AutomatedReport>277*/-27814 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J282283— 285Z usagesprivate function buildSortedQuery(string $sor286- 288/*** Get all active and enabled reports with ac 289291* @param string $frequency292-293* dreturn cocLectron<Aucomacedкeрort»29423 usages295public function getActiveReportsByFrequency(s296297$this->logger->info('AskAnything request received', ['user_id' => $user-›getId(),'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') .$user->getId() . flor'message_preview' →> mb_substr($request->input( key: 'message'), 0, 50),I);if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return steacureuneckitry &$inputData = $request->validated():$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,oenmer. scorvoeru Cer.UN UEMAND OCKuILCtype: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemondLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ruseconos. screankedves-›cerconnectmeour + screankequest-›cetreadiameoureturn $this->prophetService->getStreamed0rAbortedResponse(streamRequest: $streamRequest,onCompleted: function (string $assistantResponse,bool $clientAborted,, 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:37CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest,php --no-coverage 261"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersget activity ids hassees sn zero sequence number to disable first r._ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> CodeClaude Sonnet 4.6winasun leams203:0uir-o( 4 spaces...
|
NULL
|
|
11084
|
219
|
32
|
2026-04-14T09:11:49.549322+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157909549_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© Managescim-orleam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2ControllerControllerJubede Tun gecaskany cnengnescoryneuuest sreuuest. osonnesponsel...s41 X2 ^(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php18457208209210211/*** Delete Ask Anything conversation history212 Ц >public function deleteAskAnythingHistory(Request $request): JsonResponsef...}258class Automacedкeрortskepo o:A15 M4 A VLOY/*** A5k Anything - subnit question and get nesponse61627677931141151161171181191211124123241 kg* Retrieve all standard (non-Ask Jiminny) m243244* @param string $sortColumnThe column to)245* dodron scrino osorcuurection ine sort culre246247* @return Collection<AutomatedReport>24824912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}250251252253254pubuie funetion askAnything (0noenandASkAnychängRequest Snequest): StreanesiResponsel USonRes/** @var User $user */$user = $request->user();nunus→> loodelything request received', I'user_id' => $user-›getId().'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') . $user->getId() . flor'message_preview' => mb_substr($request->input( key: 'message'), 0, 50),J):if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {return $featureCheck;/*** Retrieve all Ask Liminny reports createdtry {nunourvara = orequesteovauodtredr* Oodrdll usernusenIne user Ynos259* @param string $sortColumnThe column to* Oparam string $sortDirection The sort dire200262* @return Collection<AutomatedReport>263*/—26414 usages265public function getAskJiminnyReportsByUser(- 266User $user,267string $sortColumn = 'created_at',268string ssorcbirection = "desc"): Collection {...J$requestData = ['userQuestion' => $inputData[ 'message'],'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic'history' => $this->historyService->getHistory($user,identifier: HistoryService: :$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId()):if ($teamAiContext?->getPrompt() !== null) {srequescbacal ceamAlcontext'. = preamAlcontext->getrrompt;—271Z usages272private function buildSortedQuery(string $sor273/**-274* Get all active and enabled reports with al276277* @param string $frequency278— 279$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):* dreturh coLcectzon<aucomacedкeрort>$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HIscoryservice..EVENI_IN_PRUGRESS_TYPEZ81123 usagespublic function getActiveReportsByFrequency(s)184283gctnoamPonloct = CtnoamPonloct •onfomandiii ovo (ineauoctlatan•Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:49CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisandockerdesks/nxe/ ervke /nosk/Autonape/aeport/ASkJiminnyReportActivityServiceTest.php --n-coverageCould not open input file: /app/artisarCommand dockerocker exec oocker land ioash —e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/sdrvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest.php --no-coverage 2261PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> Code Claude Sonnet 4.6Winasun leams202:00uir-o( 4 spaces...
|
NULL
|
-6592564186475551818
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© Managescim-orleam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2ControllerControllerJubede Tun gecaskany cnengnescoryneuuest sreuuest. osonnesponsel...s41 X2 ^(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php18457208209210211/*** Delete Ask Anything conversation history212 Ц >public function deleteAskAnythingHistory(Request $request): JsonResponsef...}258class Automacedкeрortskepo o:A15 M4 A VLOY/*** A5k Anything - subnit question and get nesponse61627677931141151161171181191211124123241 kg* Retrieve all standard (non-Ask Jiminny) m243244* @param string $sortColumnThe column to)245* dodron scrino osorcuurection ine sort culre246247* @return Collection<AutomatedReport>24824912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}250251252253254pubuie funetion askAnything (0noenandASkAnychängRequest Snequest): StreanesiResponsel USonRes/** @var User $user */$user = $request->user();nunus→> loodelything request received', I'user_id' => $user-›getId().'team_id' => $user->getTeamId(),'request_hash' => md5( string: $request->input( key: 'message') . $user->getId() . flor'message_preview' => mb_substr($request->input( key: 'message'), 0, 50),J):if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {return $featureCheck;/*** Retrieve all Ask Liminny reports createdtry {nunourvara = orequesteovauodtredr* Oodrdll usernusenIne user Ynos259* @param string $sortColumnThe column to* Oparam string $sortDirection The sort dire200262* @return Collection<AutomatedReport>263*/—26414 usages265public function getAskJiminnyReportsByUser(- 266User $user,267string $sortColumn = 'created_at',268string ssorcbirection = "desc"): Collection {...J$requestData = ['userQuestion' => $inputData[ 'message'],'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic'history' => $this->historyService->getHistory($user,identifier: HistoryService: :$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId()):if ($teamAiContext?->getPrompt() !== null) {srequescbacal ceamAlcontext'. = preamAlcontext->getrrompt;—271Z usages272private function buildSortedQuery(string $sor273/**-274* Get all active and enabled reports with al276277* @param string $frequency278— 279$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):* dreturh coLcectzon<aucomacedкeрort>$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HIscoryservice..EVENI_IN_PRUGRESS_TYPEZ81123 usagespublic function getActiveReportsByFrequency(s)184283gctnoamPonloct = CtnoamPonloct •onfomandiii ovo (ineauoctlatan•Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:49CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisandockerdesks/nxe/ ervke /nosk/Autonape/aeport/ASkJiminnyReportActivityServiceTest.php --n-coverageCould not open input file: /app/artisarCommand dockerocker exec oocker land ioash —e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/sdrvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest.php --no-coverage 2261PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> Code Claude Sonnet 4.6Winasun leams202:00uir-o( 4 spaces...
|
11082
|
|
11086
|
219
|
33
|
2026-04-14T09:11:52.552525+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157912552_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php x © HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2ControllerControllerJubede Tuon getAsKAnycningniscory request srequesc: ssonkesponset...s41 X2 ^(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php18411208209210211/*** Delete Ask Anything conversation history212 Ц >public function deleteAskAnythingHistory(Request $request): JsonResponsef...}258class Automacedкeрortskepo o:A15 M4 A VLOY/*** A5k Anything - subnit question and get nesponse616276931141151161171181191211124123241 kg* Retrieve all standard (non-Ask Jiminny) m243244* @param string $sortColumnThe column to)245* dodron scrino osorcuurection ine sort oulre246247* @return Collection<AutomatedReport>24824912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}250251252253254255pubizo function askAnythangCOnDenandASKAnythangRequest goquest): StreanedResponse / JsonRes/** @var User $user */$user = $request->user();nunus→> loodelything request received', I'user_id' => $user-›getId().'team_id' => $user->getTeamId(),'request_hash' => md5 ( string: $request->input( key: 'message') • $user-›getId() . flor'message_preview' => mb_substr($request->input( key: 'message'), 0, 50),J):if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return $featureCheck;/*** Retrieve all Ask Liminay reports created 257try {SinoutData = Srequest->validatedo:* Oodrdll usernusenIne user Ynos259* @param string $sortColumnThe column to* Oparam string $sortDirection The sort dire200261262* @return Collection<AutomatedReport>263*/— 26414 usages265public function getAskJiminnyReportsByUser(- 266User $user,267string $sortColumn = 'created_at',268string ssorcbirection = "desc"): Collection {...J$requestData = ['userQuestion' => $inputData[ 'message'],'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic'history' => $this->historyService->getHistory($user,identifier: HistoryService: :]:$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());if ($teamAiContext?->getPrompt() !== null) {srequescbacal ceamAlcontext'. = preamAlcontext->getrrompt;—271Z usages272private function buildSortedQuery(string $sor273/**-274* Get all active and enabled reports with al276277* @param string $frequency278— 279$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):* dreturh coLcectzon<aucomacedкeрort>$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HIscoryservice..EVENI_IN_PRUGRESS_TYPEZ81123 usagespublic function getActiveReportsByFrequency(s)184283gctnoamPonloct = CtnoamPonloct •onfomandiii ovo (ineauoctlatan•Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:52CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker lano oash—e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/ext/ drvicrs/K2psk/Autonat eReports/A5KDiman ReportActivatyServiceTest,php --no-coverage 261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsperiod date filters1de handtes scalyr flttersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> Code Claude Sonnet 4.6W Windsurf Teams203:49uir-o( 4 spaces...
|
NULL
|
6366950284980569196
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv @ ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php x © HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2ControllerControllerJubede Tuon getAsKAnycningniscory request srequesc: ssonkesponset...s41 X2 ^(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php18411208209210211/*** Delete Ask Anything conversation history212 Ц >public function deleteAskAnythingHistory(Request $request): JsonResponsef...}258class Automacedкeрortskepo o:A15 M4 A VLOY/*** A5k Anything - subnit question and get nesponse616276931141151161171181191211124123241 kg* Retrieve all standard (non-Ask Jiminny) m243244* @param string $sortColumnThe column to)245* dodron scrino osorcuurection ine sort oulre246247* @return Collection<AutomatedReport>24824912 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}250251252253254255pubizo function askAnythangCOnDenandASKAnythangRequest goquest): StreanedResponse / JsonRes/** @var User $user */$user = $request->user();nunus→> loodelything request received', I'user_id' => $user-›getId().'team_id' => $user->getTeamId(),'request_hash' => md5 ( string: $request->input( key: 'message') • $user-›getId() . flor'message_preview' => mb_substr($request->input( key: 'message'), 0, 50),J):if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) €return $featureCheck;/*** Retrieve all Ask Liminay reports created 257try {SinoutData = Srequest->validatedo:* Oodrdll usernusenIne user Ynos259* @param string $sortColumnThe column to* Oparam string $sortDirection The sort dire200261262* @return Collection<AutomatedReport>263*/— 26414 usages265public function getAskJiminnyReportsByUser(- 266User $user,267string $sortColumn = 'created_at',268string ssorcbirection = "desc"): Collection {...J$requestData = ['userQuestion' => $inputData[ 'message'],'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic'history' => $this->historyService->getHistory($user,identifier: HistoryService: :]:$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());if ($teamAiContext?->getPrompt() !== null) {srequescbacal ceamAlcontext'. = preamAlcontext->getrrompt;—271Z usages272private function buildSortedQuery(string $sor273/**-274* Get all active and enabled reports with al276277* @param string $frequency278— 279$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):* dreturh coLcectzon<aucomacedкeрort>$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HIscoryservice..EVENI_IN_PRUGRESS_TYPEZ81123 usagespublic function getActiveReportsByFrequency(s)184283gctnoamPonloct = CtnoamPonloct •onfomandiii ovo (ineauoctlatan•Tests passed: 1 (2 minutes ago), 0lablf Support Daily • in 2h 49 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:11:52CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker lano oash—e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/ext/ drvicrs/K2psk/Autonat eReports/A5KDiman ReportActivatyServiceTest,php --no-coverage 261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsperiod date filters1de handtes scalyr flttersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> Code Claude Sonnet 4.6W Windsurf Teams203:49uir-o( 4 spaces...
|
NULL
|
|
11088
|
219
|
34
|
2026-04-14T09:12:16.565275+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157936565_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.57539064,"top":0.13055556,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.58632815,"top":0.13055556,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.59765625,"top":0.12916666,"width":0.00859375,"height":0.015972223},"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.60625,"top":0.12916666,"width":0.008203125,"height":0.015972223},"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\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"}]...
|
-149015398497082264
|
-5824280399854999452
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component...
|
11086
|
|
11090
|
219
|
35
|
2026-04-14T09:12:17.442498+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157937442_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrorenvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr>D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.phpACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends ControllerA1 X2 л241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php260261262263264265266class Automacedкeрortskepo o:A15 M4 . V267268264/**270* Retrieve all standard (non-Ask Liminny) M 271214* @param string $sortColumnThe column t( 273* oparam string esortbirection ine sort dire 274616275931141151161171181191211124123* @return Collection<AutomatedReport>276*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]81282/**283* Retrieve all Ask Liminny reports created {285286* Oodrdll usernusenThe User Who: 287* @param string $sortColumnThe column tC 288* Oparam string $sortDirection The sort dire 289* @return Collection<AutomatedReport>29029'1*/— 29%14 usages293public function getAskJiminnyReportsByUser(User $user,—2742Y3string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2972983302 usagesprivate function buildSortedQuery(string $sor 332-333/**334* Get all active and enabled reports with al 335* @param string $frequency337-338* dreturh coLcectzon<aucomacedкeрort>33934023 usages341public function getActiveReportsByFrequency(§342$requestData = ['userQuestion" => SinputData'message'].'callIds' => $this->historyService->getContextIds($user,loemunel. nascor yocivie'history' => $this->historyService->getHistory($user,identifier: HistoryService::1:$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());if ($teamAiContext?->getPrompt() !== null) {$requestData['teamAiContext'] = $teamAiContext->getPromptO);Sthis->historyService->appendToUserHistorvdsuser,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: H1scoryservice..EVENI_IN_PRUGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData):// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeolreturn $this->prophetService->getStreamed0rAbortedResponse(screankeuest. screankeouest.onCompleted: functionstring $assist &tResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {...}):} catch (Exception $e) {$this->historyService->removeLastEventMessageByType($user,identher: Historyservice::UN_UENAND_SERVICElype:Hstorvservce...vaM u PRUGkeoswre$this->logger->error('Failed to process Ask Anything request', ['error' => $e->getMessage(),'user_id' => $user-›getId(),'question' => $request->input( key: 'message'),Tests passed: 1 (3 minutes ago), 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:17CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragelou nor oen nolr tler var w nunwarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker lano oasn —c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetActLeylasPassesNonzerosequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> CodeClaude Sonnet 4.6Winasun leams292:0/uir-o( 4 spaces...
|
NULL
|
-6080571630649416889
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.js vProject vEditViewNavigat PhpStormFileFV faVsco.js vProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrorenvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr>D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.phpACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends ControllerA1 X2 л241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php260261262263264265266class Automacedкeрortskepo o:A15 M4 . V267268264/**270* Retrieve all standard (non-Ask Liminny) M 271214* @param string $sortColumnThe column t( 273* oparam string esortbirection ine sort dire 274616275931141151161171181191211124123* @return Collection<AutomatedReport>276*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]81282/**283* Retrieve all Ask Liminny reports created {285286* Oodrdll usernusenThe User Who: 287* @param string $sortColumnThe column tC 288* Oparam string $sortDirection The sort dire 289* @return Collection<AutomatedReport>29029'1*/— 29%14 usages293public function getAskJiminnyReportsByUser(User $user,—2742Y3string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2972983302 usagesprivate function buildSortedQuery(string $sor 332-333/**334* Get all active and enabled reports with al 335* @param string $frequency337-338* dreturh coLcectzon<aucomacedкeрort>33934023 usages341public function getActiveReportsByFrequency(§342$requestData = ['userQuestion" => SinputData'message'].'callIds' => $this->historyService->getContextIds($user,loemunel. nascor yocivie'history' => $this->historyService->getHistory($user,identifier: HistoryService::1:$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());if ($teamAiContext?->getPrompt() !== null) {$requestData['teamAiContext'] = $teamAiContext->getPromptO);Sthis->historyService->appendToUserHistorvdsuser,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: H1scoryservice..EVENI_IN_PRUGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData):// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeolreturn $this->prophetService->getStreamed0rAbortedResponse(screankeuest. screankeouest.onCompleted: functionstring $assist &tResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {...}):} catch (Exception $e) {$this->historyService->removeLastEventMessageByType($user,identher: Historyservice::UN_UENAND_SERVICElype:Hstorvservce...vaM u PRUGkeoswre$this->logger->error('Failed to process Ask Anything request', ['error' => $e->getMessage(),'user_id' => $user-›getId(),'question' => $request->input( key: 'message'),Tests passed: 1 (3 minutes ago), 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:17CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragelou nor oen nolr tler var w nunwarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker lano oasn —c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetActLeylasPassesNonzerosequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in+ <> CodeClaude Sonnet 4.6Winasun leams292:0/uir-o( 4 spaces...
|
NULL
|
|
11093
|
219
|
36
|
2026-04-14T09:12:28.114430+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157948114_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.57539064,"top":0.13055556,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.58632815,"top":0.13055556,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.59765625,"top":0.12916666,"width":0.00859375,"height":0.015972223},"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.60625,"top":0.12916666,"width":0.008203125,"height":0.015972223},"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\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5923402359908557185
|
-5824280404149966624
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11090
|
|
11094
|
219
|
37
|
2026-04-14T09:12:32.359820+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157952359_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:C ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D ControllersV MAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (3 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGAskJIminnykepor Acuivilyservice.ongACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller41 M2 ^(e TrackProvidernstallled-vent.ono241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp→ ounouLbala lllessauer© CreateActivityLoggedEvent.php© UserPilotActivityListener.php262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic263'history' => $this->historyService->getHistory($user,identifier: HistoryService::• ActivityLogged.phpAutomatedReportsCallbackService.php264C RequestGenerateAskJiminnyReportJob.php265266$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId()):RequestGenerateReportJob.php© AutomatedReportResult.phpif ($teamAiContext?->getPrompt() !== null) {(C) AutomatedReport.php268"reouescvaral'teanaucontext' = "reanazcontext->deurronotoclass Automacedкeрortskepo o:A15 X4 Av20961627593114115116117118119121123LI4/**273* Retrieve all standard (non-Ask Jiminny) M274* @param string $sortColumnThe column to276*dparam string ssortulrection ine sort dire277* @return Collection<AutomatedReport>.278279*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]84285/**286287* Retrieve all Ask Liminny reports created A288* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column te290* Oparam string $sortDirection The sort dire2911475* @return Collection<AutomatedReport>294*/-29514 usages296public function getAskJiminnyReportsByUser(User $user,298string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}300301—302Z usagesprivate function buildSortedQuery(string $sor]305504/**—305306* Get all active and enabled reports with ac—307308* @param string $frequency309— 310* dreturh coLcectzon<aucomacedкeрort>31131223 usagespublic function getActiveReportsByFrequency(s)314$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeot):rerur uns-porooneroeru ce-poerotreanecuraoorteoresconsestreankeovest, "strealikecuest.onCompleted: function (string $assistantResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {// Remove in-progress eventSthis->historyService->removeLastEventMessageByType($user,identifier: HistoryService: : ON_DEMAND_SERVICE,type: HistorvService::EVENT IN PROGRESS TYPE// Save to history if backend completed successfully (even if client discor// Only skip saving if there was an actual error during streamingif (! $hadError && ! empty(trim($assistantResponse))) {$this->historyService->appendToSystemHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$assistantResponse,, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:32CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land ioash —eSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisaniminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest-php --no-coverage 2>61"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturnsfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51 - added 'sequence_number' = 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.sequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirsO filesystems.phprlleutiiong• FilterNormalizer.php app/UtilsrleutllestonoFlesvstem-xcention.ohvFileNotFoundException.php app/Exceptions/Fltervormalizerlect.ohnO Filter.phpO FileService.phpReportActivityService.php +1 -1O FilterDefinition.phpExplain it to me again. Why is there issue with that? Where is it expected and wy do I need to fork with that. How is it used in efi y+ <> CodeClaude Sonnet 4.6Öul ..Vew allliReject allAccept allWinasun leams298:48uir-o( 4 spaces...
|
NULL
|
6021502683580180874
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:C ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D ControllersV MAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (3 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGAskJIminnykepor Acuivilyservice.ongACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller41 M2 ^(e TrackProvidernstallled-vent.ono241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp→ ounouLbala lllessauer© CreateActivityLoggedEvent.php© UserPilotActivityListener.php262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic263'history' => $this->historyService->getHistory($user,identifier: HistoryService::• ActivityLogged.phpAutomatedReportsCallbackService.php264C RequestGenerateAskJiminnyReportJob.php265266$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId()):RequestGenerateReportJob.php© AutomatedReportResult.phpif ($teamAiContext?->getPrompt() !== null) {(C) AutomatedReport.php268"reouescvaral'teanaucontext' = "reanazcontext->deurronotoclass Automacedкeрortskepo o:A15 X4 Av20961627593114115116117118119121123LI4/**273* Retrieve all standard (non-Ask Jiminny) M274* @param string $sortColumnThe column to276*dparam string ssortulrection ine sort dire277* @return Collection<AutomatedReport>.278279*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]84285/**286287* Retrieve all Ask Liminny reports created A288* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column te290* Oparam string $sortDirection The sort dire2911475* @return Collection<AutomatedReport>294*/-29514 usages296public function getAskJiminnyReportsByUser(User $user,298string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}300301—302Z usagesprivate function buildSortedQuery(string $sor]305504/**—305306* Get all active and enabled reports with ac—307308* @param string $frequency309— 310* dreturh coLcectzon<aucomacedкeрort>31131223 usagespublic function getActiveReportsByFrequency(s)314$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeot):rerur uns-porooneroeru ce-poerotreanecuraoorteoresconsestreankeovest, "strealikecuest.onCompleted: function (string $assistantResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {// Remove in-progress eventSthis->historyService->removeLastEventMessageByType($user,identifier: HistoryService: : ON_DEMAND_SERVICE,type: HistorvService::EVENT IN PROGRESS TYPE// Save to history if backend completed successfully (even if client discor// Only skip saving if there was an actual error during streamingif (! $hadError && ! empty(trim($assistantResponse))) {$this->historyService->appendToSystemHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$assistantResponse,, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:32CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land ioash —eSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisaniminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest-php --no-coverage 2>61"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturnsfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51 - added 'sequence_number' = 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.sequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirsO filesystems.phprlleutiiong• FilterNormalizer.php app/UtilsrleutllestonoFlesvstem-xcention.ohvFileNotFoundException.php app/Exceptions/Fltervormalizerlect.ohnO Filter.phpO FileService.phpReportActivityService.php +1 -1O FilterDefinition.phpExplain it to me again. Why is there issue with that? Where is it expected and wy do I need to fork with that. How is it used in efi y+ <> CodeClaude Sonnet 4.6Öul ..Vew allliReject allAccept allWinasun leams298:48uir-o( 4 spaces...
|
NULL
|
|
11095
|
219
|
38
|
2026-04-14T09:12:35.407620+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157955407_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:C ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D Controllersv MAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (3 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykepor Acuivilyservice.ongACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller41 M2 ^(e TrackProvidernstallled-vent.ono241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp→ ounouLbala lllessauer© CreateActivityLoggedEvent.php© UserPilotActivityListener.php262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic263'history' => $this->historyService->getHistory($user,identifier: HistoryService::• ActivityLogged.phpAutomatedReportsCallbackService.php264C RequestGenerateAskJiminnyReportJob.php265266$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());RequestGenerateReportJob.php© AutomatedReportResult.phpif ($teamAiContext?->getPrompt() !== null) {(C) AutomatedReport.php268"reouescvaral'teanaucontext' = "reanazcontext->deurronotoclass Automacedкeрortskepo o:A15 X4 Av20%61627593114115116117118119121123LI4/**273* Retrieve all standard (non-Ask Jiminny) M274* @param string $sortColumnThe column to276*dparam string ssortulrection ine sort dire277* @return Collection<AutomatedReport>.278279*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]84285/**286287* Retrieve all Ask Liminny reports created A288* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column te290* Oparam string $sortDirection The sort dire2911475* @return Collection<AutomatedReport>294*/-29514 usages296public function getAskJiminnyReportsByUser(User $user,298string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J300301—302Z usagesprivate function buildSortedQuery(string $sor]305504/**—305306* Get all active and enabled reports with ac—307308* @param string $frequency309— 310* dreturn cocLectron<Aucomacedкeрort»31131223 usagespublic function getActiveReportsByFrequency(s)314$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeou):rerur uns-porooneroeru ce-poerotreanecuraoorteoresconsestreankeovest, "strealikecuest.onCompleted: function (string $assistantResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {// Remove in-progress eventSthis->historyService->removeLastEventMessageByType($user,identifier: HistoryService: : ON_DEMAND_SERVICE,type: HistorvService::EVENT IN PROGRESS TYPE// Save to history if backend completed successfully (even if client discor// Only skip saving if there was an actual error during streamingif (! $hadError && ! empty(trim($assistantResponse))) {$this->historyService->appendToSystemHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$assistantResponse,, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:35CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ..Now let's run the test to verifvdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsperiod date filters1de handtes scalyr flttersget activity ids hassees sn zero sequence number to disable first r._ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]<>CodeClaude Sonnet 4.6W Windsurf Teams298:48uir-o( 4 spaces...
|
NULL
|
-4836243511905384773
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:C ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D Controllersv MAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (3 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykepor Acuivilyservice.ongACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller41 M2 ^(e TrackProvidernstallled-vent.ono241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp→ ounouLbala lllessauer© CreateActivityLoggedEvent.php© UserPilotActivityListener.php262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic263'history' => $this->historyService->getHistory($user,identifier: HistoryService::• ActivityLogged.phpAutomatedReportsCallbackService.php264C RequestGenerateAskJiminnyReportJob.php265266$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());RequestGenerateReportJob.php© AutomatedReportResult.phpif ($teamAiContext?->getPrompt() !== null) {(C) AutomatedReport.php268"reouescvaral'teanaucontext' = "reanazcontext->deurronotoclass Automacedкeрortskepo o:A15 X4 Av20%61627593114115116117118119121123LI4/**273* Retrieve all standard (non-Ask Jiminny) M274* @param string $sortColumnThe column to276*dparam string ssortulrection ine sort dire277* @return Collection<AutomatedReport>.278279*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]84285/**286287* Retrieve all Ask Liminny reports created A288* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column te290* Oparam string $sortDirection The sort dire2911475* @return Collection<AutomatedReport>294*/-29514 usages296public function getAskJiminnyReportsByUser(User $user,298string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J300301—302Z usagesprivate function buildSortedQuery(string $sor]305504/**—305306* Get all active and enabled reports with ac—307308* @param string $frequency309— 310* dreturn cocLectron<Aucomacedкeрort»31131223 usagespublic function getActiveReportsByFrequency(s)314$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeou):rerur uns-porooneroeru ce-poerotreanecuraoorteoresconsestreankeovest, "strealikecuest.onCompleted: function (string $assistantResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {// Remove in-progress eventSthis->historyService->removeLastEventMessageByType($user,identifier: HistoryService: : ON_DEMAND_SERVICE,type: HistorvService::EVENT IN PROGRESS TYPE// Save to history if backend completed successfully (even if client discor// Only skip saving if there was an actual error during streamingif (! $hadError && ! empty(trim($assistantResponse))) {$this->historyService->appendToSystemHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$assistantResponse,, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:35CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ..Now let's run the test to verifvdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsperiod date filters1de handtes scalyr flttersget activity ids hassees sn zero sequence number to disable first r._ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]<>CodeClaude Sonnet 4.6W Windsurf Teams298:48uir-o( 4 spaces...
|
11094
|
|
11097
|
219
|
39
|
2026-04-14T09:12:44.194401+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157964194_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.js#11894 on JY-18909-automated-reports-ask-liminny k vProject v© ReportController.phpJiminnybeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 48 mA100% C•Tue 14 Apr 12:12:44AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContlests passed:1 (s minutes ago= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykeporiAcuivilyservice.ong© ActivitySearch.pnp© Criteria.phpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...(e) TrackProvidernstallled-vent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpsronodeclare(strict_types=1);Nowersrunthe esto vertvA1 X2 ^© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 лnamespace Jiminny\Http\Controllers\API\V2;>use...class OnDemandV2Controller extends Controlleruse AurnorizeskeQvests/*** Retrieve all standard (non-Ask Jiminny) Mprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;tests/unxt/Servzces/Kiosk/Automate/keports/AskJ1minyRepprtActivityServiceTest.php --no-coverageloul nor oen ndlr Tler var ww nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const array FILTER_KEY_EXCLUDED_PARAMS = [• docker exec docker lamo 1 bash -c "find / -name artisan -maxdenth 6 2>/dev/null | head -5"61' sequence_number',/home/jiminny/artisan* @return Collection<AutomatedReport>'page',*/'per_page',12 usagesLniLTe".iminny && php artisan testpublic function getAllStandardReports(oTTset,•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"string $sortColumn = 'created_at',];PASSstring $sortDirection = 'desc'getTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturns): Collection {...}public function __construct(a fittersemoty when no resultsperiod date filters/**private readonly Activitysrch $activitySearch,1de handtes scalyr fltters75* Retrieve all Ask Liminny reports created&private readonly HistoryService ShistoryService,get activity ids hassees sn zero sequence number to disable first r._ 0.025private readonly ProphetService SprophetService,* Oodrdll usernusenIne user Ynosprivate readonly TeamAiContextRepository $teamAiContextRepository,All 8 tests pass. Here's a summary:* @param string $sortColumnThe column toprivate readonly ActiveStreamsRepository $activeStreamsRepository,* Oparam string $sortDirection The sort direprivace readonly evencuispaccher gevenculsparcher.Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0orivace readonly Loccerintertace ologder* @return Collection<AutomatedReport>) f...3Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:*/Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesi14 usagespublic function getAskJiminnyReportsByUser(* Cheok 1f the user's tean has the ASK. JTMIMVYLON ANYTHTNG featune enabtedActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tilterUser $user,*/The frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicestring $sortColumn = 'created_at',returee o.string ssorcbirection = "desc"private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse{..3Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstReque): Collection {...Jst() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirs2 usages* Get top N activity IDs for Ask Jiminny feature based on filterstRequest () === false.private function buildSortedQuery(string $sorÖul ..114* Othrows ValidationException115/**116* Get all active and enabled reports with al* ethravs AotävityPnovzdenexcept2on117118* @param string $frequency78 (gg>public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositorVew allliItlle win changesv119126app/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1* dreturh coLcectzon<aucomaredкeport.Reject allAccept all121127private function hasChangedContextFilter(Request $request, User $user): boolf...}Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in23 usages1571124public function getActiveReportsByFrequency([EMAIL]<> Code123Claude Sonnet 4.6W Windsurf Teams498:48uir-o( 4 spaces...
|
NULL
|
-5243517845311795936
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.js#11894 on JY-18909-automated-reports-ask-liminny k vProject v© ReportController.phpJiminnybeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 48 mA100% C•Tue 14 Apr 12:12:44AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContlests passed:1 (s minutes ago= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykeporiAcuivilyservice.ong© ActivitySearch.pnp© Criteria.phpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...(e) TrackProvidernstallled-vent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpsronodeclare(strict_types=1);Nowersrunthe esto vertvA1 X2 ^© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 лnamespace Jiminny\Http\Controllers\API\V2;>use...class OnDemandV2Controller extends Controlleruse AurnorizeskeQvests/*** Retrieve all standard (non-Ask Jiminny) Mprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;tests/unxt/Servzces/Kiosk/Automate/keports/AskJ1minyRepprtActivityServiceTest.php --no-coverageloul nor oen ndlr Tler var ww nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const array FILTER_KEY_EXCLUDED_PARAMS = [• docker exec docker lamo 1 bash -c "find / -name artisan -maxdenth 6 2>/dev/null | head -5"61' sequence_number',/home/jiminny/artisan* @return Collection<AutomatedReport>'page',*/'per_page',12 usagesLniLTe".iminny && php artisan testpublic function getAllStandardReports(oTTset,•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"string $sortColumn = 'created_at',];PASSstring $sortDirection = 'desc'getTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturns): Collection {...}public function __construct(a fittersemoty when no resultsperiod date filters/**private readonly Activitysrch $activitySearch,1de handtes scalyr fltters75* Retrieve all Ask Liminny reports created&private readonly HistoryService ShistoryService,get activity ids hassees sn zero sequence number to disable first r._ 0.025private readonly ProphetService SprophetService,* Oodrdll usernusenIne user Ynosprivate readonly TeamAiContextRepository $teamAiContextRepository,All 8 tests pass. Here's a summary:* @param string $sortColumnThe column toprivate readonly ActiveStreamsRepository $activeStreamsRepository,* Oparam string $sortDirection The sort direprivace readonly evencuispaccher gevenculsparcher.Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0orivace readonly Loccerintertace ologder* @return Collection<AutomatedReport>) f...3Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:*/Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesi14 usagespublic function getAskJiminnyReportsByUser(* Cheok 1f the user's tean has the ASK. JTMIMVYLON ANYTHTNG featune enabtedActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tilterUser $user,*/The frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicestring $sortColumn = 'created_at',returee o.string ssorcbirection = "desc"private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse{..3Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstReque): Collection {...Jst() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirs2 usages* Get top N activity IDs for Ask Jiminny feature based on filterstRequest () === false.private function buildSortedQuery(string $sorÖul ..114* Othrows ValidationException115/**116* Get all active and enabled reports with al* ethravs AotävityPnovzdenexcept2on117118* @param string $frequency78 (gg>public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositorVew allliItlle win changesv119126app/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1* dreturh coLcectzon<aucomaredкeport.Reject allAccept all121127private function hasChangedContextFilter(Request $request, User $user): boolf...}Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used in23 usages1571124public function getActiveReportsByFrequency([EMAIL]<> Code123Claude Sonnet 4.6W Windsurf Teams498:48uir-o( 4 spaces...
|
NULL
|
|
11100
|
219
|
40
|
2026-04-14T09:12:48.179088+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157968179_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpJiminnybeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 48 mA100% C•Tue 14 Apr 12:12:48AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg› D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContlests passed: l(s minutes ago= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.phg© ActivitySearch.pnp© Criteria.phpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..(e TrackProvidernstallled-vent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpsronodeclare(strict_types=1);Now let's run the test to verifvA1 X2 ^w© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 ^namespace Jiminny\Http\Controllers\API\V2;>use...class OnDemandV2Controller extends Controller61use AurnorizeskeQvests/*** Retrieve all standard (non-Ask Jiminny) Mprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const array FILTER_KEY_EXCLUDED_PARAMS = [' sequence_number',* @return Collection<AutomatedReport>'page','per_page',12 usages'limit',public function getAllStandardReports(oTTset,string $sortColumn = 'created_at',];string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created&* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort direpublic function __construct(private readonly ActivitySearch $actfivitySearch,private readonly HistoryService ShistoryService,private readonly ProphetService SprophetService,private readonly TeamAiContextRepository $teamAiContextRepository,private readonly ActiveStreamsRepository $activeStreamsRepository,private readonly eventulspaccher pevencuispaccher,orivace readonly Loccerintertace ologder* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor/*** Get all active and enabled reports with al* @param string $frequency* check if the usen's tean has the ASK. JTMTMIV, ON ANYTHTING featune enabted*/private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse{..3* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* ethrous ActivityprovidenExceptiontests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioash —d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/sdrvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest.php --no-coverage 2261PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Oul .1141151161171181191211124123* dreturh coLcectzon<aucomaredкeport.23 usagespublic function getActiveReportsByFrequency(s78 (gg>public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositorItlle wiun changesv126app/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1127private function hasChangedContextFilter(Request $request, User $user): boolf...}Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Vew allliReject allAccept allW Windsurf Teams48:45uir-o( 4 spaces...
|
NULL
|
-5166163523971095501
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpJiminnybeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 48 mA100% C•Tue 14 Apr 12:12:48AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg› D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContlests passed: l(s minutes ago= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.phg© ActivitySearch.pnp© Criteria.phpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..(e TrackProvidernstallled-vent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpsronodeclare(strict_types=1);Now let's run the test to verifvA1 X2 ^w© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 ^namespace Jiminny\Http\Controllers\API\V2;>use...class OnDemandV2Controller extends Controller61use AurnorizeskeQvests/*** Retrieve all standard (non-Ask Jiminny) Mprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const array FILTER_KEY_EXCLUDED_PARAMS = [' sequence_number',* @return Collection<AutomatedReport>'page','per_page',12 usages'limit',public function getAllStandardReports(oTTset,string $sortColumn = 'created_at',];string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created&* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort direpublic function __construct(private readonly ActivitySearch $actfivitySearch,private readonly HistoryService ShistoryService,private readonly ProphetService SprophetService,private readonly TeamAiContextRepository $teamAiContextRepository,private readonly ActiveStreamsRepository $activeStreamsRepository,private readonly eventulspaccher pevencuispaccher,orivace readonly Loccerintertace ologder* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor/*** Get all active and enabled reports with al* @param string $frequency* check if the usen's tean has the ASK. JTMTMIV, ON ANYTHTING featune enabted*/private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse{..3* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* ethrous ActivityprovidenExceptiontests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioash —d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/sdrvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest.php --no-coverage 2261PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Oul .1141151161171181191211124123* dreturh coLcectzon<aucomaredкeport.23 usagespublic function getActiveReportsByFrequency(s78 (gg>public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositorItlle wiun changesv126app/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1127private function hasChangedContextFilter(Request $request, User $user): boolf...}Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Vew allliReject allAccept allW Windsurf Teams48:45uir-o( 4 spaces...
|
11097
|
|
11102
|
219
|
41
|
2026-04-14T09:12:50.291571+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157970291_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phg© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© AskJiminnyReportActivityServiceTest.phpsrono© HistoryService.phpA console [PROD]© ActivitySearch.pnp© Criteria.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php(e TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpnamespace Jiminny\Http\Controllers\API\V2;>use...class OnDemandV2Controller extends Controllerclass Automacedкeрortskepo o:A15 X4 ^6175761141151161171181191211124use Aurnorizeskeovests/*** Retrieve all standard (non-Ask Jiminny) Mprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const array FILTER_KEY_EXCLUDED_PARAMS = [' sequence_number',* @return Collection<AutomatedReport>'page',*/'per_page',12 usagesLniLTe".public function getAllStandardReports(oTTset,string $sortColumn = 'created_at',];string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created&* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort direpublic function __construct(private readonly ActivitySearch IctivitySearch,private readonly HistoryService ShistoryService,private readonly ProphetService SprophetService,private readonly TeamAiContextRepository $teamAiContextRepository,private readonly ActiveStreamsRepository $activeStreamsRepository,privace readonly evencuispaccher gevenculsparcher.orivace readonly Loccerintertace ologder* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor/*** Get all active and enabled reports with ac* @param string $frequency78 (gg>126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(: 157lests passed: l(s minutes ago, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:50CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvA1 X2 ^wprivate function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponsef.../*** Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException*/tests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragelou nor oen nolr tler var w nunwarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/ drvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest,php --no-coverage 2261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsperiod date filters1de handtes scalyr flttersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Oul .Vew alllipublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositorItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allprivate function hasChangedContextFilter(Request $request, User $user): boolf...}Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Winasun leams55:8uir-o( 4 spaces...
|
NULL
|
7349304024954283664
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phg© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© AskJiminnyReportActivityServiceTest.phpsrono© HistoryService.phpA console [PROD]© ActivitySearch.pnp© Criteria.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php(e TrackProvidernstallled-vent.onodeclare(strict_types=1);© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpnamespace Jiminny\Http\Controllers\API\V2;>use...class OnDemandV2Controller extends Controllerclass Automacedкeрortskepo o:A15 X4 ^6175761141151161171181191211124use Aurnorizeskeovests/*** Retrieve all standard (non-Ask Jiminny) Mprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const array FILTER_KEY_EXCLUDED_PARAMS = [' sequence_number',* @return Collection<AutomatedReport>'page',*/'per_page',12 usagesLniLTe".public function getAllStandardReports(oTTset,string $sortColumn = 'created_at',];string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created&* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort direpublic function __construct(private readonly ActivitySearch IctivitySearch,private readonly HistoryService ShistoryService,private readonly ProphetService SprophetService,private readonly TeamAiContextRepository $teamAiContextRepository,private readonly ActiveStreamsRepository $activeStreamsRepository,privace readonly evencuispaccher gevenculsparcher.orivace readonly Loccerintertace ologder* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor/*** Get all active and enabled reports with ac* @param string $frequency78 (gg>126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(: 157lests passed: l(s minutes ago, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:50CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvA1 X2 ^wprivate function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponsef.../*** Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException*/tests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragelou nor oen nolr tler var w nunwarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/ drvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest,php --no-coverage 2261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsperiod date filters1de handtes scalyr flttersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Oul .Vew alllipublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositorItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allprivate function hasChangedContextFilter(Request $request, User $user): boolf...}Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Winasun leams55:8uir-o( 4 spaces...
|
NULL
|
|
11104
|
219
|
42
|
2026-04-14T09:12:54.034915+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157974034_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr>D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (4 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© AskJiminnyReportActivityServiceTest.php© HistoryService.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpCc W .*THAT :(e TrackProvidernstallled-vent.onoQ- activitySearchdeclare(strict_types=1);© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Http\Controllers\API\V2;>use...© AutomatedReportResult.phpclass OnDemandV2Controller extends Controllerclass Automacedкeрortskepo o:815 X4 л611141151161171181191211124123use Aurnorizeskeovests/*** Retrieve all standard (non-Ask Jiminny) Mprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const array FILTER_KEY_EXCLUDED_PARAMS = [' sequence_number',* @return Collection<AutomatedReport>'page',*/'per_page',12 usagesLniLTe".public function getAllStandardReports(oTTset,string $sortColumn = 'created_at',];string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created&* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort direpublic function __construct(private readonly ActivitySearch $eprivate readonly HistoryService $ExtractSurround// =private readonly ProphetService Spropnetservice,private readonly TeamAiContextRepository $teamAiContextRepository,private readonly ActiveStreamsRepository $activeStreamsRepository,privace readonly evencuispaccher gevenculsparcher.orivace readonly Loccerintertace ologder* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor/*** Get all active and enabled reports with ac* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>78 (gg>12623 usages12271public function getActiveReportsByFrequency(: 157, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:53CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwA1X2 A Vtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragelou nor oen nolr tler var w nunwarusanprivate function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponsef.../*** Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException*/Command dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/ drvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest,php --no-coverage 2261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsperiod date filters1de handtes scalyr flttersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew alllipublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositorItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allprivate function hasChangedContextFilter(Request $request, User $user): boolf...}Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]< CodeClaude Sonnet 4.6W Windsurf Teams48:0014 charsuir-o( 4 spaces...
|
NULL
|
7820031517870746076
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr>D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> MAccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (4 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© AskJiminnyReportActivityServiceTest.php© HistoryService.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpCc W .*THAT :(e TrackProvidernstallled-vent.onoQ- activitySearchdeclare(strict_types=1);© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny\Http\Controllers\API\V2;>use...© AutomatedReportResult.phpclass OnDemandV2Controller extends Controllerclass Automacedкeрortskepo o:815 X4 л611141151161171181191211124123use Aurnorizeskeovests/*** Retrieve all standard (non-Ask Jiminny) Mprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const array FILTER_KEY_EXCLUDED_PARAMS = [' sequence_number',* @return Collection<AutomatedReport>'page',*/'per_page',12 usagesLniLTe".public function getAllStandardReports(oTTset,string $sortColumn = 'created_at',];string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created&* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort direpublic function __construct(private readonly ActivitySearch $eprivate readonly HistoryService $ExtractSurround// =private readonly ProphetService Spropnetservice,private readonly TeamAiContextRepository $teamAiContextRepository,private readonly ActiveStreamsRepository $activeStreamsRepository,privace readonly evencuispaccher gevenculsparcher.orivace readonly Loccerintertace ologder* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor/*** Get all active and enabled reports with ac* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>78 (gg>12623 usages12271public function getActiveReportsByFrequency(: 157, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:53CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwA1X2 A Vtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragelou nor oen nolr tler var w nunwarusanprivate function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponsef.../*** Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException*/Command dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/ drvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest,php --no-coverage 2261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsperiod date filters1de handtes scalyr flttersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew alllipublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositorItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allprivate function hasChangedContextFilter(Request $request, User $user): boolf...}Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]< CodeClaude Sonnet 4.6W Windsurf Teams48:0014 charsuir-o( 4 spaces...
|
11102
|
|
11107
|
219
|
43
|
2026-04-14T09:12:59.446754+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157979446_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
activitySearch
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
2/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.30546874,"top":0.13472222,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.3203125,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"activitySearch","depth":4,"bounds":{"left":0.33320314,"top":0.13402778,"width":0.0515625,"height":0.013888889},"value":"activitySearch","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.3953125,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.40703124,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4171875,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.42734376,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2/2","depth":4,"bounds":{"left":0.44335938,"top":0.13333334,"width":0.030078124,"height":0.015277778},"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.4734375,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.48359376,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.49375,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.50390625,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.5992187,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1218936328987935876
|
-3962810862232569982
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
activitySearch
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
2/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vyJiminnyDeouecommana.ong© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© Managescim-orleam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv C ControllersV MAPI> DAiCallScoringD AReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (4 minutes ago)© ReportController.php© AutomatedReportsCommand.php= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.phgActiviysearch.php© HistoryService.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© AskJiminnyReportActivityServiceTest.phpactivitySearch© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:(e TrackProvidernstallled-vent.onoclass OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.php) Aulomaleakeporscallbackservice.ono© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л616293114115116117118119121/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..+100/*** Recrieve ald Ask Jaminny reporus created* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>110*/-11114 usages112public function getAskJiminnyReportsByUser(-113User $user,114string $sortColumn = 'created_at',115string ssorcbirection = "desc"): Collection {...J116117—118Z usagesprivate function buildSortedQuery(string $sor]1191/**-121122* Get all active and enabled reports with al124* @param string $frequency125—12k* dreturh coLcectzon<aucomacedкeрort>127/** @var User $user */$user = $request->user();if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {return $featureCheck;$topCount = $request->input( key:too count.oeraull SelT.aUrrAUL UF ALNUIC CUUNtry &// Always fetch first N (top count) IDs$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::crarray_merge($request->all(), ['limit' => $topCount,'page' →> 11),$user->getTimezone()sfiltenSet = Sthis-ctivitySeancil-→getonDemagadPage/i1terSet(SonDemandActivitySeane$validationRules = $filterSet->getValidationRules()->merge ([excuude → array"'limit' => 'integer|min:1|max:'.$topCount,->all():$request->validate($validationRules);$hasChangedFilters = $this->hasChangedContextFilter(Srequest, $user);nacuvirvios = revositorv-›onvenanosearchlosunuvsuser, sonvenanoAcavltvsearchuranuns-omstorvseru ceeos corerontextos nuserleenuuer. Tstrorvserucer.cumiels.return new JsonResponse(['count' => count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAlias: :HTTP_0K);} catch (Exception $e) {$this->logger->error('Failed to fetch activity IDs for Ask Liminny', ['error' => $e->getMessage(),"User_1d" → suser->gecla,1):return new JsonResponsedl'ids' => [1,'error' => 'Failed to fetch activity IDs',status: ResponseALias: :HTTP_INTERNAL_SERVER_ERROR);private function hasChangedContextFilter(Request $request, User $user): boolf...}23 usagespublic function getActiveReportsByFrequency(≤1571124123, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:59CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Nowersrunthe esto vertvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var ww nunbarusandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxe erckee/Kio5/AutonateReports/5KJimamyReportActivaty ServiceTest, php --no-coverage 2561"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]<> CodeClaude Sonnet 4.6W Windsurf Teams95:64uir-o( 4 spaces...
|
NULL
|
|
11109
|
219
|
44
|
2026-04-14T09:13:03.282911+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157983282_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnannerc PnoAom.ono© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...}1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac222* @param string $frequency140121124125—126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(s157activitySearchclass OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user():itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count',default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezoneterSet = $this->activitySearch->get0nDeman|dPageFiffterSet($onDemandActivitySearchCriteria, $uselidationRules= $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,1)->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,monvelanorcoutyoearchuteria, onureros->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error' => $e-›getMessage(),'user_id'→User-paerloirn new JsonResponse(['ids' => [],'error"'Failed to fetch activity IDs',status: ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);Pulon nascnanceocontextUser $user): boolf..}Tests passed: 1 (4 minutes ago)Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:13:03CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragelou nor oen nolr tler var w nunwarusandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioasn —"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivitvourationRande → min duration = 1 Ttlters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6W Windsur leams9o:o.uir-o( 4 spaces...
|
NULL
|
-9206226249325314020
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnannerc PnoAom.ono© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...}1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac222* @param string $frequency140121124125—126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(s157activitySearchclass OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user():itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count',default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezoneterSet = $this->activitySearch->get0nDeman|dPageFiffterSet($onDemandActivitySearchCriteria, $uselidationRules= $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,1)->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,monvelanorcoutyoearchuteria, onureros->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error' => $e-›getMessage(),'user_id'→User-paerloirn new JsonResponse(['ids' => [],'error"'Failed to fetch activity IDs',status: ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);Pulon nascnanceocontextUser $user): boolf..}Tests passed: 1 (4 minutes ago)Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:13:03CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragelou nor oen nolr tler var w nunwarusandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioasn —"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivitvourationRande → min duration = 1 Ttlters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6W Windsur leams9o:o.uir-o( 4 spaces...
|
11107
|
|
11111
|
219
|
45
|
2026-04-14T09:13:17.692160+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157997692_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
activitySearch
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
1/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.30546874,"top":0.13472222,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.3203125,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"activitySearch","depth":4,"bounds":{"left":0.33320314,"top":0.13402778,"width":0.0515625,"height":0.013888889},"value":"activitySearch","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.3953125,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.40703124,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4171875,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.42734376,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1/2","depth":4,"bounds":{"left":0.44335938,"top":0.13333334,"width":0.030078124,"height":0.015277778},"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.4734375,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.48359376,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.49375,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.50390625,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.5992187,"top":0.13263889,"width":0.01015625,"height":0.016666668},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.57539064,"top":0.15972222,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.58632815,"top":0.15972222,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.59765625,"top":0.15833333,"width":0.00859375,"height":0.015972223},"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.60625,"top":0.15833333,"width":0.008203125,"height":0.015972223},"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\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-661265807901631934
|
-5802339713239498621
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
activitySearch
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
1/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}...
|
NULL
|
|
11113
|
219
|
46
|
2026-04-14T09:13:20.904523+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158000904_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© AskJiminnyReportActivityServiceTest.php© HistoryService.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) mu* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort culre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac222* @param string $frequency140121124125—126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(s157activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user(0):itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', (default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezoneterSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $usenidationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,1)->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,monvelanorcoutvoearchurtera, onurerois->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAlias::HTTP_0K);(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error' => $e-›getMessage(),'user_id'→ ser-roerloirn new JsonResponse(['ids' »> [].'error"'Failed to fetch activity IDs',status: ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);Pulon nasunanceocontex:Filter(Request $request, User $user): boolf...}Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:20+D ..Tests passed: 1 (4 minutes ago)CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepNow let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusandecke nte/sdocxes /kLosk/Ruonape/arports/ASkJ1ninyReportActivityservicetest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioasn —Sid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivitvourationRande → min duration = 1 tlters ouf o-second activifiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest () === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allEColoimianovzcontro, Uer-iS there isue with that? Where is it expected and wty do I need to forx with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Winasun leams95:67uir-o( 4 spaces...
|
NULL
|
-341284272545293047
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© AskJiminnyReportActivityServiceTest.php© HistoryService.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) mu* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort culre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac222* @param string $frequency140121124125—126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(s157activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user(0):itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', (default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezoneterSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $usenidationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,1)->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,monvelanorcoutvoearchurtera, onurerois->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAlias::HTTP_0K);(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error' => $e-›getMessage(),'user_id'→ ser-roerloirn new JsonResponse(['ids' »> [].'error"'Failed to fetch activity IDs',status: ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);Pulon nasunanceocontex:Filter(Request $request, User $user): boolf...}Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:20+D ..Tests passed: 1 (4 minutes ago)CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepNow let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusandecke nte/sdocxes /kLosk/Ruonape/arports/ASkJ1ninyReportActivityservicetest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioasn —Sid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivitvourationRande → min duration = 1 tlters ouf o-second activifiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest () === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allEColoimianovzcontro, Uer-iS there isue with that? Where is it expected and wty do I need to forx with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Winasun leams95:67uir-o( 4 spaces...
|
11111
|
|
11115
|
219
|
47
|
2026-04-14T09:13:23.583515+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158003583_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProvider~ D ControllersV DAPI> DAiCallScoringD AReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (4 minutes ago)© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc 106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac 223.* @param string $frequency140121124125—126* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s15activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user():itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezone)terSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $uselidationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,$onDemandActivitySearchCriteria,$filterS.s->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAL1as::HTTP_0K)*(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error'=ne->oerressade'user_id'=> $user->getId(),irn new JsonResponse(['ids' => [],'error"'Failed to fetch activity IDs',status: ResponseAL1as::HTTP_INTERNAL_SERVER_ERROR)NloalSupport Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:23CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sandecke nte/sdocxes /kLosk/Ruonape/arports/ASkJ1ninyReportActivityservicetest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest- php --no-coverage 2>&1"PASSNAucomaLeanepores Askstminnyneportactevilyserviceresemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (fiiters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirs-Requesto zzz tallse.Öul ..1 file with changesapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Vew allliReject allAccept allExplain it to me aaain. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used inPSW Windsurf Teams9567uir-o( 4 spaces...
|
NULL
|
-3642487540369125113
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProvider~ D ControllersV DAPI> DAiCallScoringD AReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (4 minutes ago)© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc 106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac 223.* @param string $frequency140121124125—126* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s15activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user():itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezone)terSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $uselidationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,$onDemandActivitySearchCriteria,$filterS.s->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAL1as::HTTP_0K)*(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error'=ne->oerressade'user_id'=> $user->getId(),irn new JsonResponse(['ids' => [],'error"'Failed to fetch activity IDs',status: ResponseAL1as::HTTP_INTERNAL_SERVER_ERROR)NloalSupport Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:23CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sandecke nte/sdocxes /kLosk/Ruonape/arports/ASkJ1ninyReportActivityservicetest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest- php --no-coverage 2>&1"PASSNAucomaLeanepores Askstminnyneportactevilyserviceresemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (fiiters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirs-Requesto zzz tallse.Öul ..1 file with changesapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Vew allliReject allAccept allExplain it to me aaain. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used inPSW Windsurf Teams9567uir-o( 4 spaces...
|
NULL
|
|
11116
|
219
|
48
|
2026-04-14T09:13:26.564212+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158006564_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© AskJiminnyReportActivityServiceTest.php© HistoryService.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc 106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac222* @param string $frequency140121124125—126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(s157activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user(0):itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', (default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezoneterSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $useridationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,1)->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,monvelanorcoutyoearchuteria, onureros->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAlias::HTTP_0K);(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error' => $e-›getMessage(),'user_id'→ ser-roerloirn new JsonResponse(['ids' »> [].'error"'Failed to fetch activity IDs',status: ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);Pulon nasunanceocontex:Filter(Request $request, User $user): boolf...}Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:26+D ..Tests passed: 1 (4 minutes ago)CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepNow let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioasn —Sid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivitvourationRande → min duration = 1 Ttlters ouf o-second activifiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Itlle wiun changesv1l/Sethicha/kios /AutomatedReports/D AskJiminyReportActivityService.,php +1 - 1Vew allliReject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Winasun leams95:67uir-o( 4 spaces...
|
NULL
|
7239342745067674649
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© AskJiminnyReportActivityServiceTest.php© HistoryService.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc 106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac222* @param string $frequency140121124125—126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(s157activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user(0):itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', (default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezoneterSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $useridationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,1)->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,monvelanorcoutyoearchuteria, onureros->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAlias::HTTP_0K);(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error' => $e-›getMessage(),'user_id'→ ser-roerloirn new JsonResponse(['ids' »> [].'error"'Failed to fetch activity IDs',status: ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);Pulon nasunanceocontex:Filter(Request $request, User $user): boolf...}Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:26+D ..Tests passed: 1 (4 minutes ago)CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepNow let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioasn —Sid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivitvourationRande → min duration = 1 Ttlters ouf o-second activifiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Itlle wiun changesv1l/Sethicha/kios /AutomatedReports/D AskJiminyReportActivityService.,php +1 - 1Vew allliReject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Winasun leams95:67uir-o( 4 spaces...
|
11115
|
|
11117
|
219
|
49
|
2026-04-14T09:13:44.926791+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158024926_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorTools#1894 on.lY-18909-automated-renorts-ask-liminnvWindowHelpProject v© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg› D Formats› D Guards> D Helpersv UHttp> DJ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D Settings> D Teaminsights•nemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybebuecommana.ongAutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 ^6162/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcuurection ine sor a* @return Collection<AutomatedReport>*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/*** Retrieve all Ask Liminny reports create* Oodrdll usernusenIne user* @param string $sortColumnThe column* Oparam string $sortDirection The sort a* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUserUser $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© OnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.phpA console [PROD]© ActivitySearch.pnp© Criteria.phpFind in Flles100+ matches in 26+ fllesFile mask*.phpsequenceIn ProjectModuleDirectoryScopeI/ Expand the chunk to a valid UTF-8 sequenceProphetClient.php 162private ?int Ssequence Number = null;ActivityLog.php 16public function geiSequenceNumber(): ?intActivityLog.php 43return Sthis-> sequenceNumber;ActivityLog.php 45public function hasSequenceNumber(): boolActivityLog.php 48etum onis-›secuencerumoer == nuirActivityLog.php 50public function sefSequenceNumber(?int #sequenceNumber): ActivityLogActivityLog.php 53Sthis->sequenceNumber = $sequence Number;ActivityLog.php 55protected $sequenceNumber;Conferences/ConferenceEvent.php 36* @param nulllint #sequenceNumberConferences/ConferenceEvent.php 48public function _construct(Activity $activity, ?string $context = null, ?int $sequence Nui Conferences/ConferenceEvent.php 50Sthis->sequenceNumber = Ssequence Vumber;Conferences/ConferenceEvent.php 54public function geiSequence Number(): ?intConferences/ConferenceEvent.php 72return Sthis->seqnceNumber;Conferences/ConferenceEvent.php 74protected Ssequence Number;ConnectionEvent.php 30* @param int|null $sequenceNumberConnectionEvent.php 41->orderBy(sequence', 'asc');API/ActivityController.php 1833ActivityDurationRange.php app/Component/ActivitySearch/FilterDefinitionprivate function getLowerBoundary(): ?intif ($this->criteria->hasMinDurationO)) {retur uns-ocrrera-oetranuuraron.oreturn $this->criteria->isFirstRequest()? static::INITIAL_MIN: nult;private function getUpperBoundary(): ?intif ($this->criteria->hasMaxDurationO)) {return punis->eriterla->gechaxburactono.2 usages110093114115116117118119121private function buildSortedQuery(string $101recurn nuee./*** Get all active and enabled reports with104* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»103105106107110811A9 Atprivate function getValue(): arrayreturn [$this->getLowerBoundary(), $this->getUpperBoundaryO];23 usages• Open results in new tabOpen in Find Window1124123public function getActiveReportsByFrequency(sSupport Daily • in 2h 47 mAAsk.liminnvRenortActivitvServicel.. De aults100% C•Tue 14 Apr 12:13:44CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Nowersrunthe esto vertvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockerdecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6W Windsurf Teams95:67uir-oia 4 space...
|
NULL
|
-6248265976633033538
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorTools#1894 on.lY-18909-automated-renorts-ask-liminnvWindowHelpProject v© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg› D Formats› D Guards> D Helpersv UHttp> DJ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D Settings> D Teaminsights•nemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybebuecommana.ongAutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 ^6162/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcuurection ine sor a* @return Collection<AutomatedReport>*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/*** Retrieve all Ask Liminny reports create* Oodrdll usernusenIne user* @param string $sortColumnThe column* Oparam string $sortDirection The sort a* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUserUser $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© OnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.phpA console [PROD]© ActivitySearch.pnp© Criteria.phpFind in Flles100+ matches in 26+ fllesFile mask*.phpsequenceIn ProjectModuleDirectoryScopeI/ Expand the chunk to a valid UTF-8 sequenceProphetClient.php 162private ?int Ssequence Number = null;ActivityLog.php 16public function geiSequenceNumber(): ?intActivityLog.php 43return Sthis-> sequenceNumber;ActivityLog.php 45public function hasSequenceNumber(): boolActivityLog.php 48etum onis-›secuencerumoer == nuirActivityLog.php 50public function sefSequenceNumber(?int #sequenceNumber): ActivityLogActivityLog.php 53Sthis->sequenceNumber = $sequence Number;ActivityLog.php 55protected $sequenceNumber;Conferences/ConferenceEvent.php 36* @param nulllint #sequenceNumberConferences/ConferenceEvent.php 48public function _construct(Activity $activity, ?string $context = null, ?int $sequence Nui Conferences/ConferenceEvent.php 50Sthis->sequenceNumber = Ssequence Vumber;Conferences/ConferenceEvent.php 54public function geiSequence Number(): ?intConferences/ConferenceEvent.php 72return Sthis->seqnceNumber;Conferences/ConferenceEvent.php 74protected Ssequence Number;ConnectionEvent.php 30* @param int|null $sequenceNumberConnectionEvent.php 41->orderBy(sequence', 'asc');API/ActivityController.php 1833ActivityDurationRange.php app/Component/ActivitySearch/FilterDefinitionprivate function getLowerBoundary(): ?intif ($this->criteria->hasMinDurationO)) {retur uns-ocrrera-oetranuuraron.oreturn $this->criteria->isFirstRequest()? static::INITIAL_MIN: nult;private function getUpperBoundary(): ?intif ($this->criteria->hasMaxDurationO)) {return punis->eriterla->gechaxburactono.2 usages110093114115116117118119121private function buildSortedQuery(string $101recurn nuee./*** Get all active and enabled reports with104* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»103105106107110811A9 Atprivate function getValue(): arrayreturn [$this->getLowerBoundary(), $this->getUpperBoundaryO];23 usages• Open results in new tabOpen in Find Window1124123public function getActiveReportsByFrequency(sSupport Daily • in 2h 47 mAAsk.liminnvRenortActivitvServicel.. De aults100% C•Tue 14 Apr 12:13:44CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Nowersrunthe esto vertvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockerdecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6W Windsurf Teams95:67uir-oia 4 space...
|
NULL
|
|
11119
|
219
|
50
|
2026-04-14T09:13:51.741141+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158031741_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Find in Files
100+ matches in 26+ files
File mask: Find in Files
100+ matches in 26+ files
File mask:
*.php
*.php
Auto
*.php
Filter Search Results
Pin Window
Search History
sequence...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Find in Files","depth":1,"bounds":{"left":0.30039063,"top":0.12291667,"width":0.02890625,"height":0.011805556},"role_description":"text"},{"role":"AXStaticText","text":"100+ matches in 26+ files","depth":1,"bounds":{"left":0.33398438,"top":0.12291667,"width":0.062109374,"height":0.011805556},"role_description":"text"},{"role":"AXCheckBox","text":"File mask:","depth":1,"bounds":{"left":0.5167969,"top":0.12013889,"width":0.034765624,"height":0.017361112},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"*.php","depth":1,"bounds":{"left":0.5527344,"top":0.11736111,"width":0.0328125,"height":0.023611112},"value":"*.php","role_description":"combo box","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"*.php","depth":6,"role_description":"text"},{"role":"AXStaticText","text":"Auto","depth":6,"role_description":"text"},{"role":"AXTextField","text":"*.php","depth":2,"bounds":{"left":0.55742186,"top":0.12291667,"width":0.013671875,"height":0.011805556},"value":"*.php","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":1,"bounds":{"left":0.590625,"top":0.12013889,"width":0.00859375,"height":0.015277778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pin Window","depth":1,"bounds":{"left":0.6015625,"top":0.12013889,"width":0.00859375,"height":0.015277778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":1,"bounds":{"left":0.296875,"top":0.14722222,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"sequence","depth":2,"bounds":{"left":0.30976564,"top":0.14722222,"width":0.2511719,"height":0.015277778},"value":"sequence","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
4679965429740400895
|
-8952663104527760037
|
click
|
accessibility
|
NULL
|
Find in Files
100+ matches in 26+ files
File mask: Find in Files
100+ matches in 26+ files
File mask:
*.php
*.php
Auto
*.php
Filter Search Results
Pin Window
Search History
sequence...
|
11117
|
|
11122
|
219
|
51
|
2026-04-14T09:13:55.327734+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158035327_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp#1894 on.lY-18909-automated-renorts-ask-liminnvProject v© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg› D Formats› D Guards> D Helpersv UHttp> DJ AccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsights•nemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ongAutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(©) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 л6162/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcuurection ine sor a* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports create* Oodrdll usernusenIne user* @param string $sortColumnIne cocumn* Oparam string $sortDirection The sort a* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUserUser $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© OnDemandV2Controller.php© HistoryService.php© FilterDetinitionCollection.php© Criteria.phpFind in Flles100+ matches in 26 + flles* File mask:*.phpsequenceIn Project ModuleDirectoryScopepublic function se SequenceNumber(?int #sequenceNumber): ActivityLogActivityLog.php 53$this->sequnceNumber = Ssequence Number;ActivityLog.php 55protected SsequenceNiConferences/ConferenceEvent.php 36* @param nulllint $sequenceNumberConferences/ConferenceEvent.php 48ouo c Tuncron constuct ActVt baciviv Stine ocontex= nul. entsequence ui conerences conterenceEvent.php 50Sthis->sequencesecuence vumberconterences/conterencecvent.ono o4oubllc tunctionence numbero. aintConferences/ConfererIceEvent.php 72return $this->sequConferences/Conferer1ceEvent.php 74protected $sequencConnectionEvent.php 30* @param int|null $seConnectionEvent.php 41->orderBy(sequAPI/ActivityController.php 1833LayoutManagementController.php 69ence_number=1 into Srequest->get to not apply default filters.Srequest->offsetSet(sequence_number', 1);sequence_number',sequence => 'required |integer|min:0|max:100',sequence' => $this->request-> input((sequence)),PartnerController.php 111er.php 112OnDemandV2Contkoller.php 40secroncreraconolerono 45SectionCriteriaController.ohp 50ActivityDurationRange.php app/Component/ActivitySearch/FilterDefinitionprivate function getLowerBoundary(): ?intif ($this->criteria->hasMinDurationO)) {retur uns-ocrrera-oetranuuraron.oreturn $this->criteria->isFirstRequest()? static::INITIAL_MIN: nult;private function getUpperBoundary(): ?intif ($this->criteria->hasMaxDurationO)) {return punis->eriterla->gechaxburactono.2 usages110093114115116117118119121private function buildSortedQuery(string $101recurn nuee./*** Get all active and enabled reports with104* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>103105106107110811A9 Atprivate function getValue(): arrayreturn [$this->getLowerBoundary(), $this->getUpperBoundaryO];23 usages• Open results in new tabOpen in Find Window1124123public function getActiveReportsByFrequency(sSupport Daily • in 2h 47 mAAsk.liminnvRenortActivitvServicel.. De aults100% |45]Tue 14 Apr 12:13:55CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Nowersrunthe esto vertvCommand dockenwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6W Windsurf Teams95:67uir-oia 4 space...
|
NULL
|
5697030713730699228
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp#1894 on.lY-18909-automated-renorts-ask-liminnvProject v© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg› D Formats› D Guards> D Helpersv UHttp> DJ AccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsights•nemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ongAutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(©) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 л6162/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcuurection ine sor a* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports create* Oodrdll usernusenIne user* @param string $sortColumnIne cocumn* Oparam string $sortDirection The sort a* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUserUser $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© OnDemandV2Controller.php© HistoryService.php© FilterDetinitionCollection.php© Criteria.phpFind in Flles100+ matches in 26 + flles* File mask:*.phpsequenceIn Project ModuleDirectoryScopepublic function se SequenceNumber(?int #sequenceNumber): ActivityLogActivityLog.php 53$this->sequnceNumber = Ssequence Number;ActivityLog.php 55protected SsequenceNiConferences/ConferenceEvent.php 36* @param nulllint $sequenceNumberConferences/ConferenceEvent.php 48ouo c Tuncron constuct ActVt baciviv Stine ocontex= nul. entsequence ui conerences conterenceEvent.php 50Sthis->sequencesecuence vumberconterences/conterencecvent.ono o4oubllc tunctionence numbero. aintConferences/ConfererIceEvent.php 72return $this->sequConferences/Conferer1ceEvent.php 74protected $sequencConnectionEvent.php 30* @param int|null $seConnectionEvent.php 41->orderBy(sequAPI/ActivityController.php 1833LayoutManagementController.php 69ence_number=1 into Srequest->get to not apply default filters.Srequest->offsetSet(sequence_number', 1);sequence_number',sequence => 'required |integer|min:0|max:100',sequence' => $this->request-> input((sequence)),PartnerController.php 111er.php 112OnDemandV2Contkoller.php 40secroncreraconolerono 45SectionCriteriaController.ohp 50ActivityDurationRange.php app/Component/ActivitySearch/FilterDefinitionprivate function getLowerBoundary(): ?intif ($this->criteria->hasMinDurationO)) {retur uns-ocrrera-oetranuuraron.oreturn $this->criteria->isFirstRequest()? static::INITIAL_MIN: nult;private function getUpperBoundary(): ?intif ($this->criteria->hasMaxDurationO)) {return punis->eriterla->gechaxburactono.2 usages110093114115116117118119121private function buildSortedQuery(string $101recurn nuee./*** Get all active and enabled reports with104* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>103105106107110811A9 Atprivate function getValue(): arrayreturn [$this->getLowerBoundary(), $this->getUpperBoundaryO];23 usages• Open results in new tabOpen in Find Window1124123public function getActiveReportsByFrequency(sSupport Daily • in 2h 47 mAAsk.liminnvRenortActivitvServicel.. De aults100% |45]Tue 14 Apr 12:13:55CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Nowersrunthe esto vertvCommand dockenwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6W Windsurf Teams95:67uir-oia 4 space...
|
NULL
|
|
11123
|
219
|
52
|
2026-04-14T09:13:57.880913+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158037880_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
activitySearch
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
1/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.30546874,"top":0.13472222,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.3203125,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"activitySearch","depth":4,"bounds":{"left":0.33320314,"top":0.13402778,"width":0.0515625,"height":0.013888889},"value":"activitySearch","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.3953125,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.40703124,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4171875,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.42734376,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1/2","depth":4,"bounds":{"left":0.44335938,"top":0.13333334,"width":0.030078124,"height":0.015277778},"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.4734375,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.48359376,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.49375,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.50390625,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.5992187,"top":0.13263889,"width":0.01015625,"height":0.016666668},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.57539064,"top":0.15972222,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.58632815,"top":0.15972222,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.59765625,"top":0.15833333,"width":0.00859375,"height":0.015972223},"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.60625,"top":0.15833333,"width":0.008203125,"height":0.015972223},"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\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","depth":4,"bounds":{"left":0.30820313,"top":0.15694444,"width":0.38359374,"height":0.84305555},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
2033549508898738106
|
-5824280404149966240
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
activitySearch
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
1/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11122
|
|
11125
|
219
|
53
|
2026-04-14T09:14:00.761730+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158040761_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity› O Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phg© HistoryService.phpA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php x© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpactivitySearchCc W.*г, Y:(e TrackProvidernstallled-vent.ono<?php© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpdeclare(strict_types=1);nanesoace Jaluunny tte controllens Arr© AutomatedReportResult.php› use ...class Automacedкeрortskepo o:A15 X4 ^61931141151161171181191211124123v class OnDemandV2Controller extends Controller/**use AuthorizesRequests;* Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}private const array [ENV_SECRET],page'per_page','limit','offset',];/*** Retrieve all Ask Liminny reports created&* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>public function __construct(private readonly ActivitySearch SactivitySearprivate readonly HistoryService ShistoryService,onvare reaconuy rrooneberuce sorooneroeruce.privace readonty leamaiconcexckeposicory eceamaicontexcкерosiсory.orivace readoncy Acclvescreamskepository saccivescrealskepositorvprivate readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor/*** Get all active and enabled reports with ac* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»189v23 usagespublic function getActiveReportsByFrequency(s/**Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:00CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwA1X2 AVo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusan* Check if the usen's tean has the ASK.JTMTMNY.ON ANYTHING featune enabledprivate function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse{…* Get top N activity IDs for Ask Jiminny feature based on filters* Ethrons VaridationException* Ethrous ActivityProvädenExceptzonCommand dockerdockerdesks/nxe/ ervke /nosk/Autonape/aeport/ASkJiminnyReportActivityServiceTest.php --n-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testtests/unxt/servaces/KLosk/AusomatedReports/AskJimaynyReportActiVatyServiceTest.php --no-coverage 2›&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat sonRande → min duration = 1 Ttllters ouf o-second acrivitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allpubLic tunction gectontexcrorAskanychingbyrilter request prequest, ElasccAculvityrepositor/** @var User $user */Explain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch< CodeClaude Sonnet 4.6W Windsurf Teams39:01.26 charsuir-o( 4 spaces...
|
NULL
|
-4383661914139117125
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity› O Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phg© HistoryService.phpA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php x© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpactivitySearchCc W.*г, Y:(e TrackProvidernstallled-vent.ono<?php© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpdeclare(strict_types=1);nanesoace Jaluunny tte controllens Arr© AutomatedReportResult.php› use ...class Automacedкeрortskepo o:A15 X4 ^61931141151161171181191211124123v class OnDemandV2Controller extends Controller/**use AuthorizesRequests;* Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* @param string $sortDirection The sort direprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}private const array [ENV_SECRET],page'per_page','limit','offset',];/*** Retrieve all Ask Liminny reports created&* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column to* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>public function __construct(private readonly ActivitySearch SactivitySearprivate readonly HistoryService ShistoryService,onvare reaconuy rrooneberuce sorooneroeruce.privace readonty leamaiconcexckeposicory eceamaicontexcкерosiсory.orivace readoncy Acclvescreamskepository saccivescrealskepositorvprivate readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor/*** Get all active and enabled reports with ac* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»189v23 usagespublic function getActiveReportsByFrequency(s/**Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:00CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwA1X2 AVo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusan* Check if the usen's tean has the ASK.JTMTMNY.ON ANYTHING featune enabledprivate function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse{…* Get top N activity IDs for Ask Jiminny feature based on filters* Ethrons VaridationException* Ethrous ActivityProvädenExceptzonCommand dockerdockerdesks/nxe/ ervke /nosk/Autonape/aeport/ASkJiminnyReportActivityServiceTest.php --n-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testtests/unxt/servaces/KLosk/AusomatedReports/AskJimaynyReportActiVatyServiceTest.php --no-coverage 2›&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat sonRande → min duration = 1 Ttllters ouf o-second acrivitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allpubLic tunction gectontexcrorAskanychingbyrilter request prequest, ElasccAculvityrepositor/** @var User $user */Explain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch< CodeClaude Sonnet 4.6W Windsurf Teams39:01.26 charsuir-o( 4 spaces...
|
NULL
|
|
11127
|
219
|
54
|
2026-04-14T09:14:06.135856+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158046135_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php(C) PropagateCoachingFee© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsD Themes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.phpCc W .*© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpactivitySearch2.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikKovalik2.10.25KOVallKI<?phpA1X2 A Vdeclare(strict_types=1);mnamesoace Jalmnny htte controulens Ar> use ...class Automacedкeрortskepo o:A15 X4 ^61931141151161171181191211124123L.lU.Lonovallk2.10.25novallk2.10.25Kovalik2.10.25Kovalik* Retrieve all standard (non-Ask Jiminny) Mclass OnDemandV2Controller extends Controlleruse AuthorizesRequests;* @param string $sortColumnThe column tc31.10.25 Ivanov* Oparam string $sortDirection The sort dire 2.10.25Kovalikprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J19.12.25Tolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolovprivate const array FILTER_KEY_EXCLUDED_PARAMS| = [sequence_nunber'page','per_page','limit','offset',/*** Retrieve all Ask Liminny reports created2.10.25Kovalik2.10.25Kovalik* Oodrdll usernusenIne user Ynos2.10.25Kovalik* @param string $sortColumnThe column tc 2.10.25Kovalik* Oparam string $sortDirection The sort dire2.10.25KOVallKIzu.ll.zo Ivanov* @return Collection<AutomatedReport>8.10.25novallk*/2.10.25Kovalik14 usages2.10.25Kovalikpublic function getAskJiminnyReportsByUser(2.10.25KovalikUser $user,2.10.25Kovalikstring $sortColumn = 'created_at',17.10.25 Kovalikstring ssorcbirection = "desc"17.10.25 Kovalik): Collection {...}17.10.25 Kovalikpublic function __construct(private readonly ActivitySearch Saprivate readonly HistoryService ShistoryService,privace readonty rropnetservice spropnetservice,privace readonty leamaiconcexckepostcory preamaiconcexckeposicory.orivace readoncy Acclvescreamskepository saccivescrealskepositorvprivate readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,) 1/*** Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled*/Ordo KoVallk2 usagesprivate function buildSortedQuery(string $sor17.10.25 Kovalik2.10.25novallk2.10.25Kovalik* Get all active and enabled reports with ac2.10.25Kovalik2.10.25* @param string $frequency2.10.25Kovalik2.10.25Kovalikonvare Tuncron checkastunnvunanyum norectureluser "user, rusonkescons* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovalik78 gPvpubuic tunccion gecconcexcrorAskanychingbyrilter kequest grequest, ElasulcA23 usagesZ.10.23Kovalikpublic function getActiveReportsByFrequency(s2.10.25Kovalik/** @var User $user */2.10.25KovalikTests passed: 1 (5 minutes ago), 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:05CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifywo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/ drvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest,php --no-coverage 2261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch‹> CodeClaude Sonnet 4.6W Windsurf Teams39:01 26 charsuir-o( 4 spaces...
|
NULL
|
6795392905184043719
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php(C) PropagateCoachingFee© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsD Themes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.phpCc W .*© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpactivitySearch2.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikKovalik2.10.25KOVallKI<?phpA1X2 A Vdeclare(strict_types=1);mnamesoace Jalmnny htte controulens Ar> use ...class Automacedкeрortskepo o:A15 X4 ^61931141151161171181191211124123L.lU.Lonovallk2.10.25novallk2.10.25Kovalik2.10.25Kovalik* Retrieve all standard (non-Ask Jiminny) Mclass OnDemandV2Controller extends Controlleruse AuthorizesRequests;* @param string $sortColumnThe column tc31.10.25 Ivanov* Oparam string $sortDirection The sort dire 2.10.25Kovalikprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J19.12.25Tolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolovprivate const array FILTER_KEY_EXCLUDED_PARAMS| = [sequence_nunber'page','per_page','limit','offset',/*** Retrieve all Ask Liminny reports created2.10.25Kovalik2.10.25Kovalik* Oodrdll usernusenIne user Ynos2.10.25Kovalik* @param string $sortColumnThe column tc 2.10.25Kovalik* Oparam string $sortDirection The sort dire2.10.25KOVallKIzu.ll.zo Ivanov* @return Collection<AutomatedReport>8.10.25novallk*/2.10.25Kovalik14 usages2.10.25Kovalikpublic function getAskJiminnyReportsByUser(2.10.25KovalikUser $user,2.10.25Kovalikstring $sortColumn = 'created_at',17.10.25 Kovalikstring ssorcbirection = "desc"17.10.25 Kovalik): Collection {...}17.10.25 Kovalikpublic function __construct(private readonly ActivitySearch Saprivate readonly HistoryService ShistoryService,privace readonty rropnetservice spropnetservice,privace readonty leamaiconcexckepostcory preamaiconcexckeposicory.orivace readoncy Acclvescreamskepository saccivescrealskepositorvprivate readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,) 1/*** Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled*/Ordo KoVallk2 usagesprivate function buildSortedQuery(string $sor17.10.25 Kovalik2.10.25novallk2.10.25Kovalik* Get all active and enabled reports with ac2.10.25Kovalik2.10.25* @param string $frequency2.10.25Kovalik2.10.25Kovalikonvare Tuncron checkastunnvunanyum norectureluser "user, rusonkescons* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovalik78 gPvpubuic tunccion gecconcexcrorAskanychingbyrilter kequest grequest, ElasulcA23 usagesZ.10.23Kovalikpublic function getActiveReportsByFrequency(s2.10.25Kovalik/** @var User $user */2.10.25KovalikTests passed: 1 (5 minutes ago), 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:05CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifywo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/ drvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest,php --no-coverage 2261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch‹> CodeClaude Sonnet 4.6W Windsurf Teams39:01 26 charsuir-o( 4 spaces...
|
11125
|
|
11129
|
NULL
|
0
|
2026-04-14T09:14:08.120867+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158048120_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php(C) PropagateCoachingFee© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsD Themes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Cor© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpCc W .*TIT:(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpactivitySearch2.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikZ.10.23KovalikKovalik2.10.25KOVallKI<?phpA1X2 A Vdeclare(strict_types=1);mnamesoace Jalmnny htte controulens Ar>use ...class Automacedкeрortskepo o:A15 X4 ^61931141151161171181191211124123L.lU.Lonovallk2.10.25novallk2.10.25Kovalik2.10.25Kovalik* Retrieve all standard (non-Ask Jiminny) Mclass OnDemandV2Controller extends Controlleruse AuthorizesRequests;* @param string $sortColumnThe column tc31.10.25 Ivanov* Oparam string $sortDirection The sort dire 2.10.25Kovalikprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolovprivate const array FILTER_KEY JE&CLUDED_PARAMS = [sequence_nunber'page','per_page','limit','offset',/*** Retrieve all Ask Liminny reports created2.10.25Kovalik2.10.25Kovalik* Oodrdll usernusenIne user Ynos2.10.25Kovalik* @param string $sortColumnThe column tc 2.10.25Kovalik* Oparam string $sortDirection The sort dire2.10.25KOVallKIzu.ll.zo Ivanov* @return Collection<AutomatedReport>8.10.25novallk*/2.10.25Kovalik14 usages2.10.25Kovalikpublic function getAskJiminnyReportsByUser(2.10.25KovalikUser $user,2.10.25Kovalikstring $sortColumn = 'created_at',17.10.25 Kovalikstring ssorcbirection = "desc"17.10.25 Kovalik): Collection {...}17.10.25 Kovalikpublic function __construct(private readonly ActivitySearch Saprivate readonly HistoryService ShistoryService,privace readonty Propnetservice spropnetservice,privace readonty leamaiconcexckepostcory preamaiconcexckeposicory.private readonly ActiveStreamsRepository $activeStreamsRepository,private readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,/*** Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled*/Ordo KoVallk2 usagesprivate function buildSortedQuery(string $sor17.10.25 Kovalik2.10.25novallk2.10.25Kovalik* Get all active and enabled reports with ac2.10.25Kovalik2.10.25* @param string $frequency2.10.25Kovalik2.10.25onvare Tuncron checkastunnvunanyum norectureluser "user, rusonkescons* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovalik78 (LPpubuic tunccion gecconcexcrorAskanychingbyrilter kequest grequest, ElasulcA23 usagesZ.10.23Kovalikpublic function getActiveReportsByFrequency(s2.10.25Kovalik/** @var User $user */2.10.25KovalikTests passed: 1 (5 minutes ago), 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:07CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/ext/ drvicrs/K2psk/Autonat eReports/A5KDiman ReportActivatyServiceTest,php --no-coverage 261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct.1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch‹> CodeClaude Sonnet 4.6winasun leams39:36uir-o( 4 spaces...
|
NULL
|
3294500289672538558
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php(C) PropagateCoachingFee© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsD Themes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Cor© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpCc W .*TIT:(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpactivitySearch2.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikZ.10.23KovalikKovalik2.10.25KOVallKI<?phpA1X2 A Vdeclare(strict_types=1);mnamesoace Jalmnny htte controulens Ar>use ...class Automacedкeрortskepo o:A15 X4 ^61931141151161171181191211124123L.lU.Lonovallk2.10.25novallk2.10.25Kovalik2.10.25Kovalik* Retrieve all standard (non-Ask Jiminny) Mclass OnDemandV2Controller extends Controlleruse AuthorizesRequests;* @param string $sortColumnThe column tc31.10.25 Ivanov* Oparam string $sortDirection The sort dire 2.10.25Kovalikprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolovprivate const array FILTER_KEY JE&CLUDED_PARAMS = [sequence_nunber'page','per_page','limit','offset',/*** Retrieve all Ask Liminny reports created2.10.25Kovalik2.10.25Kovalik* Oodrdll usernusenIne user Ynos2.10.25Kovalik* @param string $sortColumnThe column tc 2.10.25Kovalik* Oparam string $sortDirection The sort dire2.10.25KOVallKIzu.ll.zo Ivanov* @return Collection<AutomatedReport>8.10.25novallk*/2.10.25Kovalik14 usages2.10.25Kovalikpublic function getAskJiminnyReportsByUser(2.10.25KovalikUser $user,2.10.25Kovalikstring $sortColumn = 'created_at',17.10.25 Kovalikstring ssorcbirection = "desc"17.10.25 Kovalik): Collection {...}17.10.25 Kovalikpublic function __construct(private readonly ActivitySearch Saprivate readonly HistoryService ShistoryService,privace readonty Propnetservice spropnetservice,privace readonty leamaiconcexckepostcory preamaiconcexckeposicory.private readonly ActiveStreamsRepository $activeStreamsRepository,private readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,/*** Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled*/Ordo KoVallk2 usagesprivate function buildSortedQuery(string $sor17.10.25 Kovalik2.10.25novallk2.10.25Kovalik* Get all active and enabled reports with ac2.10.25Kovalik2.10.25* @param string $frequency2.10.25Kovalik2.10.25onvare Tuncron checkastunnvunanyum norectureluser "user, rusonkescons* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovalik78 (LPpubuic tunccion gecconcexcrorAskanychingbyrilter kequest grequest, ElasulcA23 usagesZ.10.23Kovalikpublic function getActiveReportsByFrequency(s2.10.25Kovalik/** @var User $user */2.10.25KovalikTests passed: 1 (5 minutes ago), 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:07CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/ext/ drvicrs/K2psk/Autonat eReports/A5KDiman ReportActivatyServiceTest,php --no-coverage 261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct.1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch‹> CodeClaude Sonnet 4.6winasun leams39:36uir-o( 4 spaces...
|
NULL
|
|
11131
|
221
|
0
|
2026-04-14T09:14:11.947514+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158051947_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsD Themes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Cor© PlaylistController.© PlaylistShareContNavicale lo the next occurrence© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpFILIER KLY EXCLUDED PARAMS© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpcc w .*TAT :(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpZ.10.23KovalikKovallik4.10.40Kovallk2.10.25Kovallk2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik<?phpA1X2 A Vaeclare strict types-1namespace Jiminny\Http\Controllers\API\V2;› use ..class Automacedкeрortskepo o:A15 X4 A619311411511611711811912111241232.10.25Kovalik2.10.25KovalikZ.10.23Kovalik* Retrieve all standard (non-Ask Jiminny) M2.10.25Kovalikclass OnDemandV2Controller extends Controlleruse Authorizeskequests)* @param string $sortColumnThe column tc 31.10.25 Ivanov* Cparam string $sortDirection The sort dire 2.10.25 Kovalikprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 NikolovN.L NKOOYprivate const array [ENV_SECRET],'per_page','limit','offset',/*** Retrieve all Ask Liminny reports created & 2.10.25Kovallk2.10.25Kovalik* Oodrdll usernusenThe user whos 2.10.25novallk* @param string $sortColumnThe column tc 2.10.25Kovalik* Oparam string $sortDirection The sort dire 2.10.25Kovalik20.11.25 Ivanov* @return Collection<AutomatedReport>8.10.25Kovalik2.10.252.10.25KovalikKovalikpublic function __construct(private readonly ActivitySearch $activitySearch,private readonly HistoryService ShistoryService,private readonly ProphetService $prophetService,private readonly TeamAiContextRepository $teamAiContextRepository,private readonly ActiveStreamsRepository $activeStreamsRepository,private readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at'string ssorcbirection = "desc"): Collection {...}2.10.2517.10.25 Kovalik17.10.25 Kovalik17.10.25 Kovalik* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled2 usages17.10.25 Kovalikprivate function buildSortedQuery(string $sor 17.10.25 Kovalik2.10.25Kovalik/**2.10.25Kovalik* Get all active and enabled reports with ac 2.10.25KovalikKovalik* @param string $frequency2.10.25Kovallik4.10.40Kovallkprivate function checkAskJiminnyOnAnythingFeature(User $user): ?JsonRespons/*** Get top N activity IDs for Ask Jiminny feature based on filtersx ocnrows vecocronexcenronx ocnrows Acenurrovloerxceorron* dreturh coLcectzon<aucomacedкeрort>23 usages2.10.25 Kovalik78 Qg >public function getContextForAskAnythingByFilter(Request $request,ElasticA2.10.25Kovalikpublic function getActiveReportsByFrequency(s7.10.25 Kovalik, 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:11CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvmand dockenwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockerdockerdesks/nxe/ ervke /nosk/Autonape/aeport/ASkJiminnyReportActivityServiceTest.php --n-coverageCould not open input file: /app/artisarCommand dockeroocker exec oocker lano oash—e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/sdrvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest.php --no-coverage 2261PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsr get activityE tatt tnt hperiod date filters•der aculvicvids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch‹ CodeClaude Sonnet 4.6W Windsurf Teams39:01.26 charsuir-o( 4 spaces...
|
NULL
|
-6591387869569782174
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsD Themes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Cor© PlaylistController.© PlaylistShareContNavicale lo the next occurrence© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpFILIER KLY EXCLUDED PARAMS© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpcc w .*TAT :(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpZ.10.23KovalikKovallik4.10.40Kovallk2.10.25Kovallk2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik<?phpA1X2 A Vaeclare strict types-1namespace Jiminny\Http\Controllers\API\V2;› use ..class Automacedкeрortskepo o:A15 X4 A619311411511611711811912111241232.10.25Kovalik2.10.25KovalikZ.10.23Kovalik* Retrieve all standard (non-Ask Jiminny) M2.10.25Kovalikclass OnDemandV2Controller extends Controlleruse Authorizeskequests)* @param string $sortColumnThe column tc 31.10.25 Ivanov* Cparam string $sortDirection The sort dire 2.10.25 Kovalikprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 NikolovN.L NKOOYprivate const array [ENV_SECRET],'per_page','limit','offset',/*** Retrieve all Ask Liminny reports created & 2.10.25Kovallk2.10.25Kovalik* Oodrdll usernusenThe user whos 2.10.25novallk* @param string $sortColumnThe column tc 2.10.25Kovalik* Oparam string $sortDirection The sort dire 2.10.25Kovalik20.11.25 Ivanov* @return Collection<AutomatedReport>8.10.25Kovalik2.10.252.10.25KovalikKovalikpublic function __construct(private readonly ActivitySearch $activitySearch,private readonly HistoryService ShistoryService,private readonly ProphetService $prophetService,private readonly TeamAiContextRepository $teamAiContextRepository,private readonly ActiveStreamsRepository $activeStreamsRepository,private readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at'string ssorcbirection = "desc"): Collection {...}2.10.2517.10.25 Kovalik17.10.25 Kovalik17.10.25 Kovalik* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled2 usages17.10.25 Kovalikprivate function buildSortedQuery(string $sor 17.10.25 Kovalik2.10.25Kovalik/**2.10.25Kovalik* Get all active and enabled reports with ac 2.10.25KovalikKovalik* @param string $frequency2.10.25Kovallik4.10.40Kovallkprivate function checkAskJiminnyOnAnythingFeature(User $user): ?JsonRespons/*** Get top N activity IDs for Ask Jiminny feature based on filtersx ocnrows vecocronexcenronx ocnrows Acenurrovloerxceorron* dreturh coLcectzon<aucomacedкeрort>23 usages2.10.25 Kovalik78 Qg >public function getContextForAskAnythingByFilter(Request $request,ElasticA2.10.25Kovalikpublic function getActiveReportsByFrequency(s7.10.25 Kovalik, 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:11CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvmand dockenwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockerdockerdesks/nxe/ ervke /nosk/Autonape/aeport/ASkJiminnyReportActivityServiceTest.php --n-coverageCould not open input file: /app/artisarCommand dockeroocker exec oocker lano oash—e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/sdrvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest.php --no-coverage 2261PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsr get activityE tatt tnt hperiod date filters•der aculvicvids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch‹ CodeClaude Sonnet 4.6W Windsurf Teams39:01.26 charsuir-o( 4 spaces...
|
11129
|
|
11132
|
221
|
1
|
2026-04-14T09:14:14.641706+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158054641_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpyJiminnyDeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 46 mA100% C•Tue 14 Apr 12:14:14AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeaminsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Cor© PlaylistController.© PlaylistShareContTests passed: 1 (5 minutes ago)= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.phpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..OnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpFILIER KEY EXCLUDED PARAMScc w .*TIT:class OnDemandV2Controller extends ControllerA1X2^private function checkAskJiminnyOnAnythingFeature(User $user): ?Jsonkespons/**Now let's run the test to verifvw(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:B15 V.4 ^2.10.25WlU.co novalik17.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikKovalik4.10.40Kovallk78 Qg >L.lU.LOnovallk 140desker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coveragecould not open input Tile: /var/www/ncml/artisan6162931141151161171181191211124123* Retrieve all standard (non-Ask Jiminny) M7.10.25Kovalik 1277.10.25 Kovalik 157* @param string $sortColumnThe column tc* @param string $sortDirection The sort dire7.10.25Kovalik1587.10.25Kovalik* @return Collection<AutomatedReport>15919.12.25 Nikolov16012 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**10.5Kovalik161Kovalik1621/.l0.zo Kovallk1637.10.25Kovalik1647.10.25Kovalik1657.10.25Kovalik1667.10.25Kovalik1677.10.25Kovalik168* Retrieve all Ask Liminny reports created7.10.25Kovalik169* Oodrdll usernusenIne user Ynos7.10.25Kovalik1707.10.25Kovalik* @param string $sortColumnThe column to171* Oparam string $sortDirection The sort dire10.5KovalikKovalikKovalik* @return Collection<AutomatedReport>7.10.25Kovallk*/9.10.2514 usages7.10.25novallkpublic function getAskJiminnyReportsByUser(7.10.25KovalikUser $user,7.10.25Kovalik179string $sortColumn = 'created_at',7.10.25180string ssorcbirection = "desc"): Collection {...J2.10.25Kovalik1812.10.25Kovalik1822 usagesZ.10.23Kovalik183private function buildSortedQuery(string $sorKovalik184k/**2.10.25KovallkZ0d2.10.25* Get all active and enabled reports with acKovallk2092.10.25novallkL102.10.25Kovalik* @param string $frequency2.10.25Kovalik212 (kg >* dreturh coLcectzon<aucomacedкeрort>23 usages2.10.25Kovalik2372.10.25Kovalik238public function getActiveReportsByFrequency(s2.10.25Kovalik2392.10.25Kovalik248* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* lochrows AcuIvityProv1derexcept1onpublic function getContextForAskAnythingByFilter(Request $request, ElasticACommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker lano oash—e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanprivate function hasChangedContextFilter(Request $request, User $user): booCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"prävate functzon makerziterkey (Request Srequest): stringCascade &e TIiminny/artisanCommand 281sfiltens = Srequest-Bexcept( keys: self::FIILTER KEYL EXCLUDED .PARAMSD ;iminny && php artisan testtests/ext/ drvicrs/K2psk/Autonat eReports/A5KDiman ReportActivatyServiceTest,php --no-coverage 261"$normalizedFilters = FilterNormalizer: :normalizeFilters($filters);$json = json_encode($normalizedFilters,flags: JSON_UNESCAPED_SLASHES/ JSON_UNESCAPED_UNICODE | JSON_THPASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturnsa fittersemoty when no results):get activityget activityE tatt tnt hperiod date filtersr get activityids bassess snazer fsequence number to disable first _ 0.025return hash(algo:"xxh3', $json);} catch (\JsonException $e) {$this->logger-›error('Failed to encode filters', ["error => se->gechessage),'filters_keys'→ array kevs oruters1):throw new AskJiminnyException( message: 'Failed to create filter key* Get Ask Anything conversation historyAll 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51 - added 'sequence_number' = 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Öul ..public function getAskAnythingHistory(Request $request): JsonResponsef...}/*** Delete Ask Anything conversation history*/public function deleteAskAnythingHistory(Request $request): JsonResponse{../**Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept all* Ask Anything - submit question and get AI responseExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6Winasun leams160:09 2o charsuir-o( 4 spaces...
|
NULL
|
-3241878322099472215
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpyJiminnyDeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 46 mA100% C•Tue 14 Apr 12:14:14AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeaminsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Cor© PlaylistController.© PlaylistShareContTests passed: 1 (5 minutes ago)= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.phpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..OnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpFILIER KEY EXCLUDED PARAMScc w .*TIT:class OnDemandV2Controller extends ControllerA1X2^private function checkAskJiminnyOnAnythingFeature(User $user): ?Jsonkespons/**Now let's run the test to verifvw(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:B15 V.4 ^2.10.25WlU.co novalik17.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikKovalik4.10.40Kovallk78 Qg >L.lU.LOnovallk 140desker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coveragecould not open input Tile: /var/www/ncml/artisan6162931141151161171181191211124123* Retrieve all standard (non-Ask Jiminny) M7.10.25Kovalik 1277.10.25 Kovalik 157* @param string $sortColumnThe column tc* @param string $sortDirection The sort dire7.10.25Kovalik1587.10.25Kovalik* @return Collection<AutomatedReport>15919.12.25 Nikolov16012 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**10.5Kovalik161Kovalik1621/.l0.zo Kovallk1637.10.25Kovalik1647.10.25Kovalik1657.10.25Kovalik1667.10.25Kovalik1677.10.25Kovalik168* Retrieve all Ask Liminny reports created7.10.25Kovalik169* Oodrdll usernusenIne user Ynos7.10.25Kovalik1707.10.25Kovalik* @param string $sortColumnThe column to171* Oparam string $sortDirection The sort dire10.5KovalikKovalikKovalik* @return Collection<AutomatedReport>7.10.25Kovallk*/9.10.2514 usages7.10.25novallkpublic function getAskJiminnyReportsByUser(7.10.25KovalikUser $user,7.10.25Kovalik179string $sortColumn = 'created_at',7.10.25180string ssorcbirection = "desc"): Collection {...J2.10.25Kovalik1812.10.25Kovalik1822 usagesZ.10.23Kovalik183private function buildSortedQuery(string $sorKovalik184k/**2.10.25KovallkZ0d2.10.25* Get all active and enabled reports with acKovallk2092.10.25novallkL102.10.25Kovalik* @param string $frequency2.10.25Kovalik212 (kg >* dreturh coLcectzon<aucomacedкeрort>23 usages2.10.25Kovalik2372.10.25Kovalik238public function getActiveReportsByFrequency(s2.10.25Kovalik2392.10.25Kovalik248* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* lochrows AcuIvityProv1derexcept1onpublic function getContextForAskAnythingByFilter(Request $request, ElasticACommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker lano oash—e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanprivate function hasChangedContextFilter(Request $request, User $user): booCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"prävate functzon makerziterkey (Request Srequest): stringCascade &e TIiminny/artisanCommand 281sfiltens = Srequest-Bexcept( keys: self::FIILTER KEYL EXCLUDED .PARAMSD ;iminny && php artisan testtests/ext/ drvicrs/K2psk/Autonat eReports/A5KDiman ReportActivatyServiceTest,php --no-coverage 261"$normalizedFilters = FilterNormalizer: :normalizeFilters($filters);$json = json_encode($normalizedFilters,flags: JSON_UNESCAPED_SLASHES/ JSON_UNESCAPED_UNICODE | JSON_THPASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturnsa fittersemoty when no results):get activityget activityE tatt tnt hperiod date filtersr get activityids bassess snazer fsequence number to disable first _ 0.025return hash(algo:"xxh3', $json);} catch (\JsonException $e) {$this->logger-›error('Failed to encode filters', ["error => se->gechessage),'filters_keys'→ array kevs oruters1):throw new AskJiminnyException( message: 'Failed to create filter key* Get Ask Anything conversation historyAll 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51 - added 'sequence_number' = 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Öul ..public function getAskAnythingHistory(Request $request): JsonResponsef...}/*** Delete Ask Anything conversation history*/public function deleteAskAnythingHistory(Request $request): JsonResponse{../**Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept all* Ask Anything - submit question and get AI responseExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6Winasun leams160:09 2o charsuir-o( 4 spaces...
|
NULL
|
|
11135
|
221
|
2
|
2026-04-14T09:14:23.387453+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158063387_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.phpC AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpFILIER KLY EXCLUDED PARAMSx 5 cc w.*TIT:© Criteria.php(e) TrackProvidernstallled-vent.onoclass unbemandvzconcroller excenas controtlenA1X2 A Vonvare tuncron checkastmunnvunanyun norectureluser "user, rusonkesconser.© CreateActivityLoggedEvent.php• ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderExceptionclass Automacedкeрortskepo o:815 X4 л61629311411511611711811912111241232.10.25KovalikO.Lo KoVallk17.10.25 Kovalik4.10.40Kovallk2.10.25novallk2.10.25Kovalik2.10.252.10.25Kovalik2.10.25KovalikKovalik78 (gg>pubLic tunction gectoncexcrorAskanychingbyrilter request prequest, ElasclcactlvZ.10.23Kovalik* Retrieve all standard (non-Ask Jiminny) MKovallk* @param string $sortColumnThe column tc7.10.25Kovallk157* @param string $sortDirection The sort direprivate function hasChangedContextFilter(Request $request, User $user): boolf.7.10.25 Kovalik* @return Collection<AutomatedReport>7.10.25 Kovalik19.12.25 Nikolov16012 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}7.10.25Kovalik7.10.25Kovalik17.10.25 Kovalik16310.5Kovalik7.10.25KovalikKovalik/**/.10.40Kovalik* Retrieve all Ask Liminny reports created & 7.10.25Kovallk7.10.25novallk169* Oodrdll usernusenThe user whos 7.10.25Kovalik170* @param string $sortColumnThe column tc 7.10.25Kovalik171* Oparam string $sortDirection The sort dire 7.10.25Kovalik7.10.25* @return Collection<AutomatedReport>7.10.257.10.259.10.25Kovalikprivate function makeFilterKey(Request $request): string$filters = $request->except( keys: self::FILTER_KEY_EXCLUDED_PARANtry f$normalizedFilters = FilterNormalizer::normaLikzeFilters($filters);$ison = json_encode(snormauizedrilters,flags: JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_return hash( algo:'xxh3', $json);7 catch (\JsonException $e) {$this->logger-›error('Failed to encode filters', ['error' => $e-›getMessage(),'filters_keys' = array_keys($filters),1):*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at'string ssorcbirection = "desc"): Collection {...Jchrow new Askuiminnyexceptionl message: "ralled to create tilter key,7.10.25Kovalllk7.10.25Kovalik7.10.25novallk2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik* Get Ask Anything conversation history*12 usagesprivate function buildSortedQuery(string $sor2.10.25 Kovalik/**2.10.25Kovalik208* Get all active and enabled reports with al2.10.25Kovalik2092.10.25Kovalik210* @param string $frequencyKovallikpublic function getAskAnythingHistory(Request Srequest): JsonResponsef...}* Delete Ask Anuthing conversation historu* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovallk2.10.25Kovalik23 usages2.10.25 Kovalikpublic function getActiveReportsByFrequency(s [IP_ADDRESS].25Kovalik240public function deleteAskAnythingHistory(Request $request): JsonResponse{...}* Ask Anything - submit question and get AI responseTests passed: 1 (5 minutes ago), 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:22CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvwdesker nte/ sockces/k.o3k/AuPo/war/orts/artiman yReportActivityserviceTest.php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisarCommand dockerocker exec oocker lano oasn —Sid php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisanCommand docken• docker exec docker lamp 1 bash -c "find / -name artisan -maxdenth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/Klosk/AusomatedReports/AskJ1maynyReportActiVatyserviceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allSynlain it to me again Whv is there iccue with that? Where is it aynected and why do nepd to work with that low is it liced [EMAIL] | am trying to fetch the activities based on savedSearch< CodeClaude Sonnet 4.6Winasun leams163.09uir-o( 4 spaces...
|
NULL
|
7948772399846250944
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.phpC AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpFILIER KLY EXCLUDED PARAMSx 5 cc w.*TIT:© Criteria.php(e) TrackProvidernstallled-vent.onoclass unbemandvzconcroller excenas controtlenA1X2 A Vonvare tuncron checkastmunnvunanyun norectureluser "user, rusonkesconser.© CreateActivityLoggedEvent.php• ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderExceptionclass Automacedкeрortskepo o:815 X4 л61629311411511611711811912111241232.10.25KovalikO.Lo KoVallk17.10.25 Kovalik4.10.40Kovallk2.10.25novallk2.10.25Kovalik2.10.252.10.25Kovalik2.10.25KovalikKovalik78 (gg>pubLic tunction gectoncexcrorAskanychingbyrilter request prequest, ElasclcactlvZ.10.23Kovalik* Retrieve all standard (non-Ask Jiminny) MKovallk* @param string $sortColumnThe column tc7.10.25Kovallk157* @param string $sortDirection The sort direprivate function hasChangedContextFilter(Request $request, User $user): boolf.7.10.25 Kovalik* @return Collection<AutomatedReport>7.10.25 Kovalik19.12.25 Nikolov16012 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}7.10.25Kovalik7.10.25Kovalik17.10.25 Kovalik16310.5Kovalik7.10.25KovalikKovalik/**/.10.40Kovalik* Retrieve all Ask Liminny reports created & 7.10.25Kovallk7.10.25novallk169* Oodrdll usernusenThe user whos 7.10.25Kovalik170* @param string $sortColumnThe column tc 7.10.25Kovalik171* Oparam string $sortDirection The sort dire 7.10.25Kovalik7.10.25* @return Collection<AutomatedReport>7.10.257.10.259.10.25Kovalikprivate function makeFilterKey(Request $request): string$filters = $request->except( keys: self::FILTER_KEY_EXCLUDED_PARANtry f$normalizedFilters = FilterNormalizer::normaLikzeFilters($filters);$ison = json_encode(snormauizedrilters,flags: JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_return hash( algo:'xxh3', $json);7 catch (\JsonException $e) {$this->logger-›error('Failed to encode filters', ['error' => $e-›getMessage(),'filters_keys' = array_keys($filters),1):*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at'string ssorcbirection = "desc"): Collection {...Jchrow new Askuiminnyexceptionl message: "ralled to create tilter key,7.10.25Kovalllk7.10.25Kovalik7.10.25novallk2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik* Get Ask Anything conversation history*12 usagesprivate function buildSortedQuery(string $sor2.10.25 Kovalik/**2.10.25Kovalik208* Get all active and enabled reports with al2.10.25Kovalik2092.10.25Kovalik210* @param string $frequencyKovallikpublic function getAskAnythingHistory(Request Srequest): JsonResponsef...}* Delete Ask Anuthing conversation historu* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovallk2.10.25Kovalik23 usages2.10.25 Kovalikpublic function getActiveReportsByFrequency(s [IP_ADDRESS].25Kovalik240public function deleteAskAnythingHistory(Request $request): JsonResponse{...}* Ask Anything - submit question and get AI responseTests passed: 1 (5 minutes ago), 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:22CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvwdesker nte/ sockces/k.o3k/AuPo/war/orts/artiman yReportActivityserviceTest.php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisarCommand dockerocker exec oocker lano oasn —Sid php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisanCommand docken• docker exec docker lamp 1 bash -c "find / -name artisan -maxdenth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/Klosk/AusomatedReports/AskJ1maynyReportActiVatyserviceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allSynlain it to me again Whv is there iccue with that? Where is it aynected and why do nepd to work with that low is it liced [EMAIL] | am trying to fetch the activities based on savedSearch< CodeClaude Sonnet 4.6Winasun leams163.09uir-o( 4 spaces...
|
11132
|
|
11137
|
221
|
3
|
2026-04-14T09:14:26.129571+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158066129_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e) TrackProvidernstallled-vent.onoOnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpFILIER KLY EXCLUDED PARAMScc w .*TIT:class unbemandvzconcroller excenas controtlenA1X2 A Vonvare tuncron checkastmunnvunanyun norectureluser "user, rusonkesconser.© CreateActivityLoggedEvent.php• ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderExceptionclass Automacedкeрortskepo o:815 X4 л61629311411511611711811912111241232.10.25KovalikU.do Kovallk17.10.25 Kovalik4.10.40Kovallk2.10.25novallk2.10.25Kovalik2.10.252.10.25Kovalik2.10.25KovalikKovalik78 (gg>pubLic tunction gectoncexcrorAskanychingbyrilter request prequest, ElasclcactlvZ.10.23Kovalik* Retrieve all standard (non-Ask Jiminny) MKovallk* @param string $sortColumnThe column tc7.10.25Kovallk157* @param string $sortDirection The sort direprivate function hasChangedContextFilter(Request $request, User $user): boolf.7.10.25 Kovalik* @return Collection<AutomatedReport>7.10.25 Kovalik19.12.25 Nikolov16012 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}7.10.25Kovalik7.10.25Kovalik17.10.25 Kovalik16310.5Kovalik7.10.25KovalikKovalik/**/.10.40Kovalik* Retrieve all Ask Liminny reports created & 7.10.25Kovallk7.10.25novallk169* Oodrdll usernusenThe user whos 7.10.25Kovalik170* @param string $sortColumnThe column tc 7.10.25Kovalik171* Oparam string $sortDirection The sort dire 7.10.25Kovalik7.10.25* @return Collection<AutomatedReport>7.10.257.10.259.10.25Kovalikprivate function makeFilterKey(Request $request): string$filters = $request->except( keys: self::FILTER_KEY_EXCLUDED_PARANtryf$normalizedFilters = FilterNormalizer::normalizeFilters($filters);$ison = json_encode(snormauizedrilters,flags: JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_return hash( algo:'xxh3', $json);} catch (\JsonException $e) {$this->logger-›error('Failed to encode filters', ['error' => $e-›getMessage(),'filters_keys' = array_keys($filters),1):*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at'string ssorcbirection = "desc"): Collection {...Jchrow new Askuiminnyexceptionl message: "ralled to create tilter key,7.10.25Kovalllk7.10.25Kovalik7.10.25novallk2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik* Get Ask Anything conversation history2 usagesprivate function buildSortedQuery(string $sor2.10.25 Kovalik/**2.10.25Kovalik208* Get all active and enabled reports with al2.10.25Kovalik2092.10.25Kovalik210* @param string $frequencyKovallikpublic function getAskAnythingHistory(Request Srequest): JsonResponsef...}* Delete Ask Anuthing conversation historu* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovallk2.10.2523 usages2.10.25 Kovalikpublic function getActiveReportsByFrequency(s [IP_ADDRESS].25Kovalik240public function deleteAskAnythingHistory(Request $request): JsonResponse{...}* Ask Anything - submit question and get AI response, 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:25CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvdesker nte/ sockces/k.o3k/AuPo/war/orts/artiman yReportActivityserviceTest.php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuPo/ape/a/ports/ASkJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisarCommand dockerocker exec oocker land ioash —eSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker lamp 1 bash -c "find / -name artisan -maxdenth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servzces/K1osk/ AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>61"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch< CodeClaude Sonnet 4.6Winasun leams163.09uir-o( 4 spaces...
|
NULL
|
7824049293423097076
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e) TrackProvidernstallled-vent.onoOnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpFILIER KLY EXCLUDED PARAMScc w .*TIT:class unbemandvzconcroller excenas controtlenA1X2 A Vonvare tuncron checkastmunnvunanyun norectureluser "user, rusonkesconser.© CreateActivityLoggedEvent.php• ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderExceptionclass Automacedкeрortskepo o:815 X4 л61629311411511611711811912111241232.10.25KovalikU.do Kovallk17.10.25 Kovalik4.10.40Kovallk2.10.25novallk2.10.25Kovalik2.10.252.10.25Kovalik2.10.25KovalikKovalik78 (gg>pubLic tunction gectoncexcrorAskanychingbyrilter request prequest, ElasclcactlvZ.10.23Kovalik* Retrieve all standard (non-Ask Jiminny) MKovallk* @param string $sortColumnThe column tc7.10.25Kovallk157* @param string $sortDirection The sort direprivate function hasChangedContextFilter(Request $request, User $user): boolf.7.10.25 Kovalik* @return Collection<AutomatedReport>7.10.25 Kovalik19.12.25 Nikolov16012 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}7.10.25Kovalik7.10.25Kovalik17.10.25 Kovalik16310.5Kovalik7.10.25KovalikKovalik/**/.10.40Kovalik* Retrieve all Ask Liminny reports created & 7.10.25Kovallk7.10.25novallk169* Oodrdll usernusenThe user whos 7.10.25Kovalik170* @param string $sortColumnThe column tc 7.10.25Kovalik171* Oparam string $sortDirection The sort dire 7.10.25Kovalik7.10.25* @return Collection<AutomatedReport>7.10.257.10.259.10.25Kovalikprivate function makeFilterKey(Request $request): string$filters = $request->except( keys: self::FILTER_KEY_EXCLUDED_PARANtryf$normalizedFilters = FilterNormalizer::normalizeFilters($filters);$ison = json_encode(snormauizedrilters,flags: JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_return hash( algo:'xxh3', $json);} catch (\JsonException $e) {$this->logger-›error('Failed to encode filters', ['error' => $e-›getMessage(),'filters_keys' = array_keys($filters),1):*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at'string ssorcbirection = "desc"): Collection {...Jchrow new Askuiminnyexceptionl message: "ralled to create tilter key,7.10.25Kovalllk7.10.25Kovalik7.10.25novallk2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik* Get Ask Anything conversation history2 usagesprivate function buildSortedQuery(string $sor2.10.25 Kovalik/**2.10.25Kovalik208* Get all active and enabled reports with al2.10.25Kovalik2092.10.25Kovalik210* @param string $frequencyKovallikpublic function getAskAnythingHistory(Request Srequest): JsonResponsef...}* Delete Ask Anuthing conversation historu* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovallk2.10.2523 usages2.10.25 Kovalikpublic function getActiveReportsByFrequency(s [IP_ADDRESS].25Kovalik240public function deleteAskAnythingHistory(Request $request): JsonResponse{...}* Ask Anything - submit question and get AI response, 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:25CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvdesker nte/ sockces/k.o3k/AuPo/war/orts/artiman yReportActivityserviceTest.php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockeldoster nxe ceockes /kJosk/AuPo/ape/a/ports/ASkJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisarCommand dockerocker exec oocker land ioash —eSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker lamp 1 bash -c "find / -name artisan -maxdenth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servzces/K1osk/ AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>61"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch< CodeClaude Sonnet 4.6Winasun leams163.09uir-o( 4 spaces...
|
NULL
|
|
11138
|
221
|
4
|
2026-04-14T09:14:41.170197+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158081170_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"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.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
3342537313573719871
|
-5967358222366069132
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
11137
|
|
11141
|
221
|
5
|
2026-04-14T09:14:43.476566+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158083476_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php©RoleChangeEventRepositol© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGASkJiminnykeportAcuivilyservice.ono xACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,© Criteria.php© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ V 3958114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m 43* @param string $sortColumnThe column to44* @param string $sortDirection The sort dire 45*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**53* Retrieve all Ask Liminny reports created f55* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column tc* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor]— 68-71/*** Get all active and enabled reports with al* @param string $frequency— 76* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace conscraint is applled - maucning che benavrour of geccontextroraskangchingbyrilte* Oreturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array €$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);=ururerta.:credcerronkedvestmargee ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);SactivityIds = $this->elasticRepository->onDemandSearchIds0nLy($user, $criteria, $filter$this->logger->info('lAskJiminnxReport] Fetched activity IDs for saved search'. L"saveo sealrcin 10→nsaveosearci-poeclou.'user id => Suser->getido'activity_count' => count($activityIds),1):return $activityIds;1 usageonivate tuncrion outuoreduestrarans-ronsearchsearch savedsearch. user "user): arrav$params = []:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValve();if (in_array($key,haystack: self::DATE_FILTER_KEYS,strict: true)) {continue;X Reject File 0* €, 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:43Fixing Ask Jiminny Rep+D ...CascadeFixing ReportControllerAutomated Report MarNow let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var ww nunbarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testtests/unxt/servaces/KLosk/AusomatedReports/AskJimaynyReportActiVatyServiceTest.php --no-coverage 2›&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allconDemandv2Controller- i5p l aem trying to tetch the activities basedd on savedSearch. THe ids in on demand and int usea [EMAIL] | am trying to fetch the activities based on savedSearch. THe ids in on demand and in<> CodeClaude Sonnet 4.6W Windsurf Teams55:54uir-o( 4 spaces...
|
NULL
|
-3978964636690427418
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php©RoleChangeEventRepositol© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGASkJiminnykeportAcuivilyservice.ono xACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,© Criteria.php© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ V 3958114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m 43* @param string $sortColumnThe column to44* @param string $sortDirection The sort dire 45*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**53* Retrieve all Ask Liminny reports created f55* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column tc* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor]— 68-71/*** Get all active and enabled reports with al* @param string $frequency— 76* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace conscraint is applled - maucning che benavrour of geccontextroraskangchingbyrilte* Oreturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array €$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);=ururerta.:credcerronkedvestmargee ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);SactivityIds = $this->elasticRepository->onDemandSearchIds0nLy($user, $criteria, $filter$this->logger->info('lAskJiminnxReport] Fetched activity IDs for saved search'. L"saveo sealrcin 10→nsaveosearci-poeclou.'user id => Suser->getido'activity_count' => count($activityIds),1):return $activityIds;1 usageonivate tuncrion outuoreduestrarans-ronsearchsearch savedsearch. user "user): arrav$params = []:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValve();if (in_array($key,haystack: self::DATE_FILTER_KEYS,strict: true)) {continue;X Reject File 0* €, 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:43Fixing Ask Jiminny Rep+D ...CascadeFixing ReportControllerAutomated Report MarNow let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen ndlr Tler var ww nunbarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testtests/unxt/servaces/KLosk/AusomatedReports/AskJimaynyReportActiVatyServiceTest.php --no-coverage 2›&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allconDemandv2Controller- i5p l aem trying to tetch the activities basedd on savedSearch. THe ids in on demand and int usea [EMAIL] | am trying to fetch the activities based on savedSearch. THe ids in on demand and in<> CodeClaude Sonnet 4.6W Windsurf Teams55:54uir-o( 4 spaces...
|
NULL
|
|
11143
|
221
|
6
|
2026-04-14T09:14:46.135279+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158086135_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJiminnykeportAcuivilyservice.ono xACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,© Criteria.php© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ V 3959114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m 43* @param string $sortColumnThe column to44* @param string $sortDirection The sort dire 45*orerur coccecconsauromareoreoor12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**53* Retrieve all Ask Liminny reports created f55* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column tc* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor]— 68-71/*** Get all active and enabled reports with al* @param string $frequency— 76* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace conscraint is applled - maucning che benavrour of geccontextroraskangchingbyrilte* @return string[] Activity IDsIpublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array €$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);=ururerta.:credcerronkedvestmargee ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);SactivityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('lAskJiminnxReport] Fetched activity IDs for saved search'. L"saveo sealrcin 10→nsaveosearci-poeclou.'user id => Suser->getido'activity_count' => count($activityIds),1):return $activityIds;1 usageonivate tuncrion outuoreduestrarans-ronsearchsearch savedsearch. user "user): arrav$params = []:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValve();if (in_array($key,haystack: self::DATE_FILTER_KEYS,strict: true)) {continue;X Reject File 0* €, 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:45CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ..Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testtests/unxt/servaces/KLosk/AusomatedReports/AskJimaynyReportActiVatyServiceTest.php --no-coverage 2›&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allSynlain it to me again Whv is there iccue with that? Where is it aynected and why do nepd to work with that low is it liced [EMAIL] | am trying to fetch the activities based on savedSearch. THe ids in on demand and in<> CodeClaude Sonnet 4.6W Windsurf Teams55:54uir-o( 4 spaces...
|
NULL
|
-284434824811040483
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJiminnykeportAcuivilyservice.ono xACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,© Criteria.php© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ V 3959114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m 43* @param string $sortColumnThe column to44* @param string $sortDirection The sort dire 45*orerur coccecconsauromareoreoor12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**53* Retrieve all Ask Liminny reports created f55* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column tc* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor]— 68-71/*** Get all active and enabled reports with al* @param string $frequency— 76* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace conscraint is applled - maucning che benavrour of geccontextroraskangchingbyrilte* @return string[] Activity IDsIpublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array €$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);=ururerta.:credcerronkedvestmargee ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);SactivityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('lAskJiminnxReport] Fetched activity IDs for saved search'. L"saveo sealrcin 10→nsaveosearci-poeclou.'user id => Suser->getido'activity_count' => count($activityIds),1):return $activityIds;1 usageonivate tuncrion outuoreduestrarans-ronsearchsearch savedsearch. user "user): arrav$params = []:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValve();if (in_array($key,haystack: self::DATE_FILTER_KEYS,strict: true)) {continue;X Reject File 0* €, 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:45CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ..Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testtests/unxt/servaces/KLosk/AusomatedReports/AskJimaynyReportActiVatyServiceTest.php --no-coverage 2›&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupin → apolies user's derault croup as a tiltelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allSynlain it to me again Whv is there iccue with that? Where is it aynected and why do nepd to work with that low is it liced [EMAIL] | am trying to fetch the activities based on savedSearch. THe ids in on demand and in<> CodeClaude Sonnet 4.6W Windsurf Teams55:54uir-o( 4 spaces...
|
11141
|
|
11144
|
221
|
7
|
2026-04-14T09:14:49.104776+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158089104_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"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.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8563436494813991353
|
-5967358188006330764
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
|
11145
|
221
|
8
|
2026-04-14T09:14:55.156439+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158095156_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php©RoleChangeEventRepositol© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReportsD AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(0 TrackProviderinstalled-vent.onv© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ V 395859114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m 43* @param string $sortColumnThe column to44* @param string $sortDirection The sort dire 45* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column toi* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/—6214 usagespublic function getAskJiminnyReportsByUser(- 64User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor]— 68-71/*** Get all active and enabled reports with al* @param string $frequency— 76* dreturn coccectron<aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© OnDemandV2Controller.php© HistoryService.phpAskJiminnykeportAcuivilyservice.ong xActiviysearch.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace conscraint is applled - macching che denavaour of geccontexchoraskanychingbyralce* Oreturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {Cascade & TICommand 9l$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);ocrurerta = urluerta.:creocerronkequestAcceptmagee ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('lAskviminnxReport] Fetchedactivity IDs for saved search', ["saveo scalrcin 10=nsaveosearci-poetlo'user id' => Suser->getido'activity_count' => count($activityIds),1):return $activityIds;Extract Surround I/ Eonivate tuncrion outuoreduestrarans-ronsearchsearch savedsearch. user "user): arrav$params = 1:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValve();if (in_array($key,continue;haystack: self::DATE_FILTER_KEYS,strict: true)) &X Reject File 0* €halSupport Daily • in 2h 46 mAU AskJiminnyReportActivityServiceT..Defaults100% [2Tue 14 Apr 12:14:54CascadeFixing ReportControllerAutomated Report M: XC Fixing Ask Jiminny R+D ...pected and why do I need to work with that. How is it used inConkSiminyCeporo/tavtyS ervite, hto tetch t shotiftie saseased on savedSearch. THe ids in on demand and inExploring.Itlle wiun changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> CodeClaude Sonnet 4.6Reject allView allAccept allW Windsurf Teamsb6:6895 chars, 22 line breaksuir-o( 4 spaces...
|
NULL
|
9183449782414629797
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php©RoleChangeEventRepositol© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReportsD AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(0 TrackProviderinstalled-vent.onv© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ V 395859114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m 43* @param string $sortColumnThe column to44* @param string $sortDirection The sort dire 45* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column toi* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/—6214 usagespublic function getAskJiminnyReportsByUser(- 64User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor]— 68-71/*** Get all active and enabled reports with al* @param string $frequency— 76* dreturn coccectron<aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© OnDemandV2Controller.php© HistoryService.phpAskJiminnykeportAcuivilyservice.ong xActiviysearch.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace conscraint is applled - macching che denavaour of geccontexchoraskanychingbyralce* Oreturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {Cascade & TICommand 9l$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);ocrurerta = urluerta.:creocerronkequestAcceptmagee ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('lAskviminnxReport] Fetchedactivity IDs for saved search', ["saveo scalrcin 10=nsaveosearci-poetlo'user id' => Suser->getido'activity_count' => count($activityIds),1):return $activityIds;Extract Surround I/ Eonivate tuncrion outuoreduestrarans-ronsearchsearch savedsearch. user "user): arrav$params = 1:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValve();if (in_array($key,continue;haystack: self::DATE_FILTER_KEYS,strict: true)) &X Reject File 0* €halSupport Daily • in 2h 46 mAU AskJiminnyReportActivityServiceT..Defaults100% [2Tue 14 Apr 12:14:54CascadeFixing ReportControllerAutomated Report M: XC Fixing Ask Jiminny R+D ...pected and why do I need to work with that. How is it used inConkSiminyCeporo/tavtyS ervite, hto tetch t shotiftie saseased on savedSearch. THe ids in on demand and inExploring.Itlle wiun changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> CodeClaude Sonnet 4.6Reject allView allAccept allW Windsurf Teamsb6:6895 chars, 22 line breaksuir-o( 4 spaces...
|
11144
|
|
11148
|
221
|
9
|
2026-04-14T09:15:00.090183+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158100090_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.jsProjectvEditViewNavigateCo PhpStormFileFV faVsco.jsProjectvEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReports(J AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ v 3958114115116117118119120/*** Retrieve all standard (non-Ask Liminny) ai 43* @param string $sortColumnThe column te 44* Cparam string $sortDirection The sort dire45*orerurn cocuecclonsauromareoredore12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}53/*** Retrieve all Ask Liminny reports created 55* Oodrdll usernusenThe User Who: 57* @param string $sortColumnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(_64User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© OnDemandV2Controller.php© HistoryService.phpAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usagespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);ocrurerta = urluerta.:creocerronkequestAccept mergeet$requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge (SrequestParams, '"Limit' => seLf::DEFAULT_TOP_ACTIVITIES_COUNT, 'page"$user->getTimezone()D:1$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filtel$this->logger->info('lAskviminnxReport] Fetchedactivity IDs for saved search', ['saved search_id' => $savedSearch-›getido.'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,naystack: seLT.:DAIE_FILIER_KEYS,strict: true)){X Reject File 0* €halSupport Daily • in 2h 46 mAAskJiminnyReportActivityServiceT...Defaults v100% [8Tue 14 Apr 12:14:59CascadeFixing ReportControllerAutomated Report Mai• Fixing Ask Jiminny R+D..again. Why is there issue with that? Where is it exected and why do I need to work with that. How is it used inased on savedSearch. THe ids in on demand and [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:wItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Reject allView allAccept allwinasun leams53:1189s chars, 2z line breaksuir-o( 4 spaces...
|
NULL
|
-4945800884558516327
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.jsProjectvEditViewNavigateCo PhpStormFileFV faVsco.jsProjectvEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReports(J AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ v 3958114115116117118119120/*** Retrieve all standard (non-Ask Liminny) ai 43* @param string $sortColumnThe column te 44* Cparam string $sortDirection The sort dire45*orerurn cocuecclonsauromareoredore12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}53/*** Retrieve all Ask Liminny reports created 55* Oodrdll usernusenThe User Who: 57* @param string $sortColumnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(_64User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© OnDemandV2Controller.php© HistoryService.phpAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usagespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);ocrurerta = urluerta.:creocerronkequestAccept mergeet$requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge (SrequestParams, '"Limit' => seLf::DEFAULT_TOP_ACTIVITIES_COUNT, 'page"$user->getTimezone()D:1$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filtel$this->logger->info('lAskviminnxReport] Fetchedactivity IDs for saved search', ['saved search_id' => $savedSearch-›getido.'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,naystack: seLT.:DAIE_FILIER_KEYS,strict: true)){X Reject File 0* €halSupport Daily • in 2h 46 mAAskJiminnyReportActivityServiceT...Defaults v100% [8Tue 14 Apr 12:14:59CascadeFixing ReportControllerAutomated Report Mai• Fixing Ask Jiminny R+D..again. Why is there issue with that? Where is it exected and why do I need to work with that. How is it used inased on savedSearch. THe ids in on demand and [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:wItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Reject allView allAccept allwinasun leams53:1189s chars, 2z line breaksuir-o( 4 spaces...
|
NULL
|
|
11150
|
221
|
10
|
2026-04-14T09:15:02.227779+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158102227_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> D AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.php© JiminnyDebugCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.php© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php< console LUlconsole SlAGiNGAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php© Criteria.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3class Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) an43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45*orerurn cocuecclonsauromareoredore12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(_64User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dateconstraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs14 usaeespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array &SrequestParams = Sthis->buiLdRequestflaramsFromSearch($savedSearch, $user);Scriteria = Criteria::createFromRequest(Accept maryeet$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,naystack: selT.:DAIE_FILIER_KEYS,strict: true)){X Reject File 0* €halSupport Daily - in 2h 45 mAAskJiminnyReportActivityServiceT...Defaults v100% [Tue 14 Apr 12:15:01CascadeFixing ReportControllerAutomated Report Mai• Fixing Ask Jiminny Ragain. Why is there issue with that? Where is it exected and why do I need to work with that. How is it used inased on savedSearch. THe ids in on demand and [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemandV2Controller.phpSurfing…+D..wItlle wiun changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6View allReject allAccept allW Windsur leams48:4uir-o( 4 spaces...
|
NULL
|
-9152860355171425029
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> D AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.php© JiminnyDebugCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.php© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php< console LUlconsole SlAGiNGAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php© Criteria.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3class Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) an43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45*orerurn cocuecclonsauromareoredore12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(_64User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dateconstraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs14 usaeespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array &SrequestParams = Sthis->buiLdRequestflaramsFromSearch($savedSearch, $user);Scriteria = Criteria::createFromRequest(Accept maryeet$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,naystack: selT.:DAIE_FILIER_KEYS,strict: true)){X Reject File 0* €halSupport Daily - in 2h 45 mAAskJiminnyReportActivityServiceT...Defaults v100% [Tue 14 Apr 12:15:01CascadeFixing ReportControllerAutomated Report Mai• Fixing Ask Jiminny Ragain. Why is there issue with that? Where is it exected and why do I need to work with that. How is it used inased on savedSearch. THe ids in on demand and [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemandV2Controller.phpSurfing…+D..wItlle wiun changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6View allReject allAccept allW Windsur leams48:4uir-o( 4 spaces...
|
11148
|
|
11151
|
221
|
11
|
2026-04-14T09:15:08.301551+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158108301_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProjectvToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php< console LUlconsole SlAGiNGASkJIminnykeportAcuivilyservice.ono xActiviysearch.php© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php© Criteria.phpclass AskJiminnyReportActivityService(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) ai 43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0public function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,xno dueconstraint is applied - matching the behaviourn of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usaeespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);Scriteria = Criteria::createFromRequest(marze t$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser: array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,naystack: SeLT::DAIE_FILIER_KEYS,strict: true)){X Reject File 0* €, 0halSupport Daily - in 2h 45 mAU AskJiminnyReportActivityServiceT….Defaults v100% CS•CascadeFixing ReportControllerAutomated Report Mar• Fixing Ask Jiminny Ragain. Why is there issue with that? Where is it exected and why do I need to work with that. How is it used ined on savedSearch. THe ids in on demand and [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OndeNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount,pace → L1,suser->geclimezoneit passes Srequest→>all() - wnich Includes sequence_number trom the URL (e.g. sequence_number=4 Trom your stagingTue 14 Apr 12:15:07+D..wItlle wiun changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6View allReject allAccept allW Windsur leams48:4uir-o( 4 spaces...
|
NULL
|
-2627250707701726651
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProjectvToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php< console LUlconsole SlAGiNGASkJIminnykeportAcuivilyservice.ono xActiviysearch.php© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php© Criteria.phpclass AskJiminnyReportActivityService(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) ai 43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0public function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,xno dueconstraint is applied - matching the behaviourn of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usaeespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);Scriteria = Criteria::createFromRequest(marze t$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser: array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,naystack: SeLT::DAIE_FILIER_KEYS,strict: true)){X Reject File 0* €, 0halSupport Daily - in 2h 45 mAU AskJiminnyReportActivityServiceT….Defaults v100% CS•CascadeFixing ReportControllerAutomated Report Mar• Fixing Ask Jiminny Ragain. Why is there issue with that? Where is it exected and why do I need to work with that. How is it used ined on savedSearch. THe ids in on demand and [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OndeNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount,pace → L1,suser->geclimezoneit passes Srequest→>all() - wnich Includes sequence_number trom the URL (e.g. sequence_number=4 Trom your stagingTue 14 Apr 12:15:07+D..wItlle wiun changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6View allReject allAccept allW Windsur leams48:4uir-o( 4 spaces...
|
NULL
|