|
11042
|
PhpStormFileFditViewNavigateCodelaraveRefactonTool PhpStormFileFditViewNavigateCodelaraveRefactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v(©) ReportController.phpJiminnybeouecommana.ong= custom.log=laravel.loge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php4 console [EUl(©) ActivityTypeService.console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.pnp(©) AskJiminnyReportAc© AutomatedReportse© AutomatedReportsSendCommand.php© AddLayoutentities.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpCi RequestGenerateAskJiminnyReportJobTest.phpC) Team.onp(©) AutomatedReportsRepository.php XIsrirstheouestX 3 Cc W *TVY:© AutomatedReportss© DealStagesService.pC) RecipientsService.ph© AutomatedReportsService.phpC CreateHeldActivityEvent.phpclass criteri61446 M3© TrackProviderInstalledEvent.php1261€ ReportSort. php€ ReportSortDirection.c) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php1204public function getLimito: int...}(©) KioskService.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php> _ Mail12001267public function isEmptyo: bool...hC RequestGenerateAskJiminnyReportJob.phpMeetingGenerator_ Notification(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php1L/112721273public function isFirstRequestO: bool_ 0Auth2(C) AutomatedReport.php1274return sthis->empty l sthis->sequenceNumber === 03RecallAlclass Automacedкeрortskepo o:815 X4 лv 1275_ security> _ StrategyL7 Streaming>MTeampublic function getOnlyActiveUsers(): boolf...}> M Telephonv* Retrieve all standard (non-Ask Jiminny) m-282*rorse a veot unstonus dure troll redves ucaroures.mone uno nucaemoru vacues ardcerua› _ UserPilotWebhook* dparam string ssorttolumnThe column Z6-204* Anaram ctnina Sconthinection The cont dinc 1285* Inis mecnod 1s speciricaclu Tor veac insionts dace rielas to supoorc une AlL clme" T..rinavecurences or isrirstreouest XTargetsu Occurrences of "isFirstReques,yn File 'Criteria.phpFound occurrences in File 'Criteria.php' 1 resultv Unc assitied " resultv Caapp 1 resultv D app/VO/Repository/OnDemandActivitySearch 1 resultv (C) OnDemandActivitvSearch/Criteria.pho 1 result140012611262126312641265126212/2 publlc tunction IsrirstReguesto: bool126812/012/11L1412741275127612841L001284198519%А12871298129111275127440a Support Daily • in 2h 51 m100% (Tue 14 Apr 12:09:56AskJiminnyReportActivityServiceT...Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny RepNow let's run the test to verifvCommand dockerltests/axt/ervkces/k3o5k/Autoatr/Rep/rtS/SrimannyReportActivtyserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusanCommand dockeldocker_docker exec docker- Lamp_1 php /app/artisarredkenorts/ask.nminnvkenortactiv1tv.ervicelest.oho =-no-coveradeCould not open input file: /app/artisarCommand dockenItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1View allReject allAccept allAsk anything (&+L)+ <> Code Claude Sonnet 4.6wpublic function getLimito: intreturn sthis->L1m1t;pubuic tunction istmptyl: boolreturn suns->elorypublic function isFirstRequestO: boolreturn sthis->empty | sthis->sequenceNumber === 0*public function getOnlyActiveUsers(): boolreturn sums->onuvactveusers === urue./*** Parse a Deal Insights date from request attributes, handling null empty values gracefully.* This method is specificallu for Deal Insights date fields to support the "All time" filter.* dparam collection sattributes* dparam string skey*dparam Davelimezone suimezone* dreturh carbonimmucable nucl/scring keturns seLf::UAlE_PARAREIER_NUI_PRUVIDED 1F parameter 15* mussing, nucl if explicitly nucl, carbonimmucable it vacla dateprivate static function parseDealInsightsDate(Collection $attributes,string Skey.lests passed: (moments agoWinasun leams 12/2:21uir-oia 4 spaces...
|
NULL
|
NULL
|
NULL
|
11042
|
|
11044
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa(ahlSupport Daily - in 2h 51 m100% C4Tue 14 Apr 12:09:5786 0Today ~...
|
NULL
|
NULL
|
NULL
|
11044
|
|
11046
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa(ahlSupport Daily - in 2h 51 m100% C4Tue 14 Apr 12:09:5886 0Today ~...
|
NULL
|
NULL
|
NULL
|
11046
|
|
11047
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsC:© AutomatedReportsSt© DealStagesService.pC) RecipientsService.ph© ReportSort.php€ ReportSortDirection.© KioskService.php> D Mail• MeetingGeneratorC NotificationDOAuth2D RecallAlD SecurityStrategyL7 Streaming>MTeam> D Telephony› _ UserPilotWebhook© AbstractService.php©ActivityProviderFactory.phj© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php©IpapiClient.php© lpapiService.php© ParticipantShareService.ph© PlanhatService.php©PlaybackService.php© PlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorinterface./©ResolveTeamCrmConnectii© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.php©TeamDeactivatedService.p©TeamOwnerService.php©TeamService.php© TranscodeParameterResol©UserService.php© Uuid.php> D Traits> D UseCases> MUser>MUtils> D Validationv DVOv D Repositoryv D OnDemandActivitySears) Criteria.php© TranscriptionKeywordP:>D TeamSettingsTests passed: 1 (a minute ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php) Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php= custom.logA console (EU]© Criteria.phpIsrirstheouest= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]A console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpX3Cc w .*TVY:class Criteria(e TrackProvidernstallled-vent.ono12161217© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php122112221226I2L1123114041236class Automacedкeрortskepo o:B15 X4 A12371241/**12421246* Retrieve all standard (non-Ask Jiminny) m 12471251* @param string $sortColumnThe column t(1252* Oparam string $sortDirection The sort dir€ 125661-1257* @return Collection<AutomatedReport>1261126212 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}1266126712711272831141151161171181191201211231274/*** Retrieve all Ask Liminny reports created À 1276-1277* Oodrdll usernusenIne User Wno:1281* @param string $sortColumnIne coLUmn c01282* @param string $sortDirection The sort dirt 1283* @return Collection<AutomatedReport>1284*/1285.128614 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',surno ssortutreccion = 'desc'): Collection {...J1ZY112922 usages1470private function buildSortedQuery(string $sor1294_12951296* Get all active and enabled reports with al 1297* @param string $frequency15111* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(sH1846 M3 ^public function getMaxCustomerQuestions(): intf..public function hasMinCommentCount(): boolf...;public function getMinCommentCount(): stringf...}public function hasMaxCommentCount(): boolf...}public function getMaxCommentCount(): stringf...public function hasSortDirection(): boolf...}public function getSortDirection(): stringf...}public function hasSortBy(): boolf...}public function getSortBy(): stringf...}public function getLimit(): intl...public function isEmpty(): boolf..public function isFirstRequest(): boolreturn schis->empagll pchis→>sequencenumber === 0,public function getOnlyActiveUsers(): boolf...}/*** Parse a Deal Insights date from request attributes,handling null/empty values graceful* This method is specifically for Deal Insights date fields to support the "All time" fil* Oparam Collection $attributes* Oparam string $key* dodron Dorelznezone outmezone=* Creturn CarbonImmutable/null/string Returns self::DATE_PARAMETER_NOT_PROVIDED if parame* missing, null if expticitty notl,carbonimmurable 1n vaclo dace4 usaeesprivate static function parseDealInsightsDate(Collection $attributes,string $key,DateTimeZone $timezone): CarbonImmutablelstringlnull f..40j Support Daily • in 2h 51 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:09:58CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvCommand dockenwdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisarCommand 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: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 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"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsget activityE 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 OFix: 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 ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ ‹> CodeClaude Sonnet 4.6Winasun leams12/2.2uir-o( 4 spaces...
|
NULL
|
NULL
|
NULL
|
11047
|
|
11048
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on.lY-18909-automated-renorts-ask-liminnvProject v© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsC:© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph© ReportSort.php€ ReportSortDirection.© KioskService.php> D Mail• MeetingGeneratorC NotificationOAuth2D RecallAlSecurityD Strategy_ streamingM TeamTelephony→ UserPilotD Webhook© AbstractService.php©ActivityProviderFactory.phj© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php© IpapiClient.php© lpapiService.php© ParticipantShareService.ph© PlanhatService.php©PlaybackService.php© PlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorInterface.© ResolveTeamCrmConnecti© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.php©) TeamDeactivatedService.p©TeamOwnerService.php©TeamService.php© TranscodeParameterResol©UserService.php© Uuid.php> D Traits> D UseCases114> MUser115>MUtils116> D Validation117v DVO118v D Repository119v D OnDemandActivitySears120© Criteria.php© TranscriptionKeywordP:>D TeamSettings= custom.logA console (EU]Criteria.php x= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]A console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpAutomatedReportsSendCommand.php© AddLayoutEntities.php,leam.ono© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpFind in Files 100+ matches in 11+ Tlles* File mask:*.php(e) TrackProvidernstallled-vent.onoisFirstRequest© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 ^/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcurection ine sor a* @return Collection<AutomatedReport>In ProjectModuleDirectoryScopeif ($group === null || | $this->criteria->isFirstRequest() (if ($this->criteria->isFirstRequest() (if ($this-> criteria->isFirstRequest() (return Sthis-> criteria->isFirstRequest0it binls-scrterar>srirstrecuesto8& $this->criteria->isFirstRequest0&& $this->criteria->isFirstRequest0)public function|isFirstRequest(): boolbool SisFirstRequestSthis->criteria->method(isFirstRequest)->willReturn(SisFirstRequest);isFirstRequest => true,t => true,=> true,isFirstRequest => false,isFirstRequest => true,isFirstRequest => true,OrganiserGroupln.php 106ActivityActualDate.php 144hte.php 158Filter Definition/ActivityDurationRange.php 90TlerverniuonAcivivreco cec.ono vsDealCloseDate.php 86Dealclosevate.ong 106OnDemandActivitySearch/Criteria.php 1272ActivityDurationRangeTest.php 56ActivityDurationRangeTest.php 62ActivityDurationRangeTest.php 63ActivityDurationRangeTest.php 78ActivityDurationRangeTest.php 85ActivityDurationRangeTest.php 92ActivityDurationRange Test.php 99ActivityDurationRangeTest.php 106Acvwvbulauonkance lest.ono is12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**OrganiserGroupln.php app/component/ActVtysearch/riiterDerinidonYoCLpubLic tunction getvalue(): arrayreturn $this->criteria->getGroupIds() ?? $this->getDefaultValue();* Retrieve all Ask Liminny reports create 101/** @return string[] */private tuncuion geuberaultvalued: array* OodrdllusernusenIne User #103*oparam scrine osorclocunnThe column 104* @param string $sortDirection The sort a105106$group = $this->executedBy->getGroup();* @return Collection<AutomatedReport>if ($group === null || ! $this->criteria->isFirstRequestO) {return []:*/14 usagespublic function getAskJiminnyReportsByUser110User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"113 Ct): Collection {...Jreturn [$group->getUvid(];public function getValidationRules(?string $prefix = null): array$team = $this->executedBy->getTeam();2 usages/**private function buildSortedQuery(string $117118119* Get all active and enabled reports with 120* @param string $frequency122123 Creturn [$prefix .uloupdu-?$prefix .'group_id.*' =>'uvid:groups, team_id,' • $team->getId(),]:public function getSortOrder(): int* dreturh coLcectzon<aucomacedкeрort>23 usages• Open results in new tabOpen in Find Windowpublic function getActiveReportsByFrequency(sSupport Daily • in 2h 50 mAAsk.liminnvRenortActivitvServicel..Defaults100% |45]Tue 14 Apr 12:10:03CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Nowersrunthe esto vertvwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusanCommand dockerdecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -d&& 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"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filters0.03sids 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.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> CodeClaude Sonnet 4.6uir-of 4 space:...
|
NULL
|
NULL
|
NULL
|
11048
|
|
11049
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa> 0ladl= Support Daily • in 2h 50 m100% <47Tue 14 Apr 12:10:0586 0Today ~...
|
NULL
|
NULL
|
NULL
|
11049
|
|
11050
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on.lY-18909-automated-renorts-ask-liminnvProject v© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsC:© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph© ReportSort.php€ ReportSortDirection.© KioskService.php> D Mail• MeetingGeneratorC NotificationOAuth2D RecallAlSecurityD Strategy_ streamingM TeamTelephony→ UserPilotD Webhook© AbstractService.php©ActivityProviderFactory.phj© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php© IpapiClient.php© lpapiService.php© ParticipantShareService.ph© PlanhatService.php©PlaybackService.php© PlaybackVideoOnlyService©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 UseCases114> MUser115>MUtils116> D Validation117v DVO118v D Repository119v D OnDemandActivitySears120© Criteria.php© TranscriptionKeywordP:>D TeamSettings= custom.logA console (EU]Criteria.php x= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]A console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpAutomatedReportsSendCommand.php© AddLayoutEntities.php,leam.ono© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpFind in Files 100+ matches in 11+ Tlles* File mask:*.php(e) TrackProvidernstallled-vent.onoisFirstRequest© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 ^/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcurection ine sor a* @return Collection<AutomatedReport>In ProjectModuleDirectoryScopeif ($group === null || | $this->criteria->isFirstRequest() (if ($this->criteria->isFirstRequest() (if ($this-> criteria->isFirstRequest() (return Sthis-> criteria->isFirstRequest0it binls-scrterar>srirstrecuesto8& $this->criteria->isFirstRequest0&& $this->criteria->isFirstRequest0)public function|isFirstRequest(): boolbool SisFirstRequestSthis->criteria->method(isFirstRequest)->willReturn (SisFirstRequest);isFirstRequest => true,t => true,=> true,isFirstRequest => false,isFirstRequest => true,isFirstRequest => true,OrganiserGroupln.php 106ActivityActualDate.php 144ActivityActualDate.php 158Filter Definition/ActivityDurationRange.php 90TlerverniuonAcivivreco cec.ono vsDealCloseDate.php 86DealcloseUate.ong 10bOnDemandActivitySearch/Criteria.php 1272AcfuityDurationRange Test.php 56ActivityDurationRangeTest.php 62ActivityDurationRangeTest.php 63ActivityDurationRangeTest.php 78ActivityDurationRangeTest.php 85ActivityDurationRangeTest.php 92ActivityDurationRange Test.php 99ActivityDurationRangeTest.php 106Acvwvbulauonkance lest.ono is12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}OrganiserGroupln.php app/component/ActVtysearch/riiterDerinidonYoCLpubLic tunction getvalue(): arrayreturn $this->criteria->getGroupIds() ?? $this->getDefaultValue();/*** Retrieve all Ask Liminny reports create 101/** @return string[] */private tuncuion geuberaultvalued: array* OodrdllusernusenIne User #103*oparam scrine osorclocunnThe column 104* @param string $sortDirection The sort a105106$group = $this->executedBy->getGroup();* @return Collection<AutomatedReport>if ($group === null || ! $this->criteria->isFirstRequestO) {return []:*/14 usagespublic function getAskJiminnyReportsByUser|110User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"113 Ct): Collection {...Jreturn [$group->getUvid(];public function getValidationRules(?string $prefix = null): array$team = $this->executedBy->getTeam();2 usages/**private function buildSortedQuery(string $117118119* Get all active and enabled reports with 120* @param string $frequency122123 Creturn [$prefix .uloupdu-?$prefix .'group_id.*' =>'uvid:groups, team_id,' • $team->getId(),]:public function getSortOrder(): int* dreturh coLcectzon<aucomacedкeрort>23 usages• Open results in new tabOpen in Find Windowpublic function getActiveReportsByFrequency(sSupport Daily • in 2h 50 mAAsk.liminnvRenortActivitvServicel..Defaults100% |45]Tue 14 Apr 12:10:05CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Nowersrunthe esto vertvwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusanCommand dockerdecke 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 -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\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filters0.03sids 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 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 win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> CodeClaude Sonnet 4.6uir-of 4 space:...
|
NULL
|
NULL
|
NULL
|
11050
|
|
11051
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa> 0ladl= Support Daily • in 2h 50 m100% <47Tue 14 Apr 12:10:0786 0Today ~...
|
NULL
|
NULL
|
NULL
|
11051
|
|
11052
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on.lY-18909-automated-renorts-ask-liminnvProject v© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsC:© AutomatedReportsSt© DealStagesService.pC) RecipientsService.ph© ReportSort.php€ ReportSortDirection.© KioskService.php> D Mail• MeetingGeneratorC NotificationOAuth2D RecallAlSecurityD Strategy_ streamingM TeamTelephony→ UserPilotD Webhook© AbstractService.php©ActivityProviderFactory.ph|© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php© IpapiClient.php© lpapiService.php© ParticipantShareService.ph© PlanhatService.php©PlaybackService.php© PlaybackVideoOnlyService©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 UseCases114> MUser115>MUtils116> D Validation117v DVO118v D Repository119v D OnDemandActivitySears120) Criteria.php© TranscriptionKeywordP:>D TeamSettings= custom.logA console (EU]Criteria.php x= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]A console [STAGING]• AskJiminnyReportActivityService.php© ActivitySearch.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpAutomatedReportsSendCommand.phpAddLayoutEntities.php,leam.ono© AutomatedReportsRepository.php XAutomaleakeporisservice.onpC CreateHeldActivityEvent.phpFind in Files 100+ matches in 11+ TllesFile mask".ohoisFirstRequest(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 ^/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcurection ine sor a*orerurn coccectlonsauromcreoreooroIn ProjectModuleDirectoryScopeif ($group === null || ! $this->criteria->isFirstRequest() (if ($this->criteria->isFirstRequest() (if ($this-> criteria->isFirstRequest() (return $this->criteria->isFirstRequest()it binls-scrterar>srirstrecuesto8& $this-> criteria->isFirstRequest()&& $this->criteria->isFirstRequest0)public function isFirstRequest(): boolbool SisFirstRequestSthis->criteria->method(isFirstRequest)->willReturn (SisFirstRequest);isFirstRequest => true,t => true,=> true,isFirstRequest => false,isFirstRequest => true,isFirstRequest => true,OrganiserGroupln.php 106ActivityActualDate.php 144ActivityActualDate.php 158FilterDefinition/ActivityDurationRange.php 90TlerverniuonAcivivreco cec.ono vsDealCloseDate.php 86DealCloseDaAt.php 106OnDemandActivitySearch/Criteria.php 1272ActivityDurationRangeTest.php 56ActivityDurationRangeTest.php 62ActivityDurationRangeTest.php 63ActivityDurationRangeTest.php 78ActivityDurationRangeTest.php 85ActivityDurationRangeTest.php 92ActivityDurationRange Test.php 99ActivityDurationRangeTest.php 106AcuvIvbu auonkancelestiono s12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**Criteria,php app/VO/Repository/OnDemandActivitySearch126412651266* Recrieve aLL ASk Jimnnu reporus create 126/1268* Oocrdlll UsernusenJne user Wzoy*oparam scrine osorclocunnIne coLumnlz/e* Oparam string $sortDirection The sort a12711272return $this->limit;public function isEmpty(): boolreturn $this->empty;public function isFirstRequest(): bool* @return Collection<AutomatedReport>*/127414 usagespublic function getAskJiminnyReportsByUser|1276User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J127812791280128111284return $this->empty || $this->sequenceNumber === 0;public function getOnlyActiveUsers(): boolreturn suns->onuvactveusers === urue.2 usages/**/**private function buildSortedQuery(string $1283* Parse a Deal Insights date from request attributes, handling null/empty values gracefully.* This method is specifically for Deal Insights date fields to support the "All time" filter* Get all active and enabled reports with 1286* @param string $frequency* Oparam Collection $attributes* @param string $key* dparam batelimezone sulmezone1289* dreturn cocLectron<Aucomacedкeрort»* Creturn CarbonImmutable/null/string Returns self::DATE_PARAMETER_NOT_PROVIDED if parameter23 usages• Open results in new tabOpen in Find Windowpublic function getActiveReportsByFrequency(sSupport Daily • in 2h 50 mAAsk.liminnvRenortActivitvServicel..Defaults100% |45]Tue 14 Apr 12:10:07CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verify:Command dockenwo docteraxe doukees /.osk/AuP /var//rts/artinam yReportActivätyServäceTest- php -no-coverageloul nor oen Indlr tler var w nunwarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.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 -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest- php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filters0.03sids 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 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 changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6uir-of 4 space:...
|
NULL
|
NULL
|
NULL
|
11052
|
|
11053
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa> 0ladl= Support Daily • in 2h 50 m100% <47Tue 14 Apr 12:10:1486 0Today ~...
|
NULL
|
NULL
|
NULL
|
11053
|
|
11054
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsC:© AutomatedReportsSt© DealStagesService.pC) RecipientsService.ph© ReportSort.php€ ReportSortDirection.© KioskService.php> D Mail• MeetingGeneratorC NotificationDOAuth2D RecallAlD SecurityStrategyL7 Streaming>MTeam> D Telephony› _ UserPilotWebhook© AbstractService.php©ActivityProviderFactory.phj© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php©IpapiClient.php© lpapiService.php© ParticipantShareService.ph© PlanhatService.php©PlaybackService.php© PlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorinterface./©ResolveTeamCrmConnectii© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.php©TeamDeactivatedService.p©TeamOwnerService.php©TeamService.php© TranscodeParameterResol©UserService.php© Uuid.php> D Traits> D UseCases> MUser>MUtils> D Validationv DVOv D Repositoryv D OnDemandActivitySears) Criteria.php© TranscriptionKeywordP:>D TeamSettingsTests passed: 1 (a minute ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.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]A console (EU]A console [STAGING]© AsKJiminnyReportActivityService.php/d• ActivitySearch.php© Criteria.php x© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpO-isFirstRequestWclass Criteria(e TrackProvidernstallled-vent.ono12161217© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php122112221226I2L1123114041236class Automacedкeрortskepo o:B15 X4 A12371241/**12421246* Retrieve all standard (non-Ask Jiminny) m 12471251* @param string $sortColumnThe column t(1252* Oparam string $sortDirection The sort dir€ 125661* @return Collection<AutomatedReport>—12571261126212 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}1266126712711272831141151161171181191201211231274/*** Retrieve all Ask Liminny reports created À 1276-1277* Oodrdll usernusenIne User Wno:1281* @param string $sortColumnIne coLUmn c01282* @param string $sortDirection The sort dirt 1283* @return Collection<AutomatedReport>1284*/1285.128614 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',surno ssortutreccion = 'desc'): Collection {...J1ZY112922 usages1470private function buildSortedQuery(string $sor1294_12951296* Get all active and enabled reports with al 1297* @param string $frequency15111* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s41846 M3 ^public function getMaxCustomerQuestions(): intf..public function hasMinCommentCount(): boolf...}public function getMinCommentCount(): stringf...}public function hasMaxCommentCount(): boolf...}public function getMaxCommentCount(): stringf...public function hasSortDirection(): boolf...}public function getSortDirection(): stringf...}public function hasSortBy(): boolf...}public function getSortBy(): stringf...}public function getLimit(): intl...public function isEmpty(): boolf..public function isFirstRequestC): boolrecurn suhis->empty ll suhis->sequencenumber === 0.public function getOnlyActiveUsers(): boolf...}/*** Parse a Deal Insights date from request attributes,handling null/empty values graceful* This method is specifically for Deal Insights date fields to support the "All time" fil* Oparam Collection $attributes* Oparam string $key* Cparam DateTimeZone $timezone=* Creturn CarbonImmutable/null/string Returns self::DATE_PARAMETER_NOT_PROVIDED if parame* missing, null if expticitty notl,CarbonImmutable if valid date4 usagesprivate static function parseDealInsightsDate(Collection $attributes,string $key,Datelimezone „timezone): CarbonImmutablelstringlnull f..Support Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:14CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvCommand dockenwo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusanCommand dockerdoster 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: 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"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsget activityE 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 OFix: 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.Oul .1 file with changesapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Vew allliReject allAccept allAsk anything (2*L)+ ‹> CodeClaude Sonnet 4.6winasun leams12/2:3014 charsuir-o( 4 spaces...
|
NULL
|
NULL
|
NULL
|
11054
|
|
11055
|
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...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
NULL
|
11055
|
|
11056
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa> 0ladl= Support Daily • in 2h 50 m100% <47Tue 14 Apr 12:10:1886 0Today ~...
|
NULL
|
NULL
|
NULL
|
11056
|
|
11057
|
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
|
NULL
|
NULL
|
11057
|
|
11058
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa> 0ladl= Support Daily • in 2h 50 m100% <47Tue 14 Apr 12:10:2086 0Today ~...
|
NULL
|
NULL
|
NULL
|
11058
|
|
11059
|
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...
|
PhpStorm
|
faVsco.js – ActivitySearch.php
|
NULL
|
11059
|
|
11060
|
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...
|
PhpStorm
|
faVsco.js – ActivitySearch.php
|
NULL
|
11060
|
|
11061
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa> 0ladl= Support Daily • in 2h 50 m100% <47Tue 14 Apr 12:10:3186 0Today ~...
|
NULL
|
NULL
|
NULL
|
11061
|
|
11062
|
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
|
NULL
|
NULL
|
11062
|
|
11063
|
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());
}
}...
|
PhpStorm
|
faVsco.js – ActivitySearch.php
|
NULL
|
11063
|
|
11064
|
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...
|
PhpStorm
|
faVsco.js – ActivitySearch.php
|
NULL
|
11064
|
|
11065
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aa> 0ladl= Support Daily • in 2h 50 m100% <47Tue 14 Apr 12:10:5086 0Today ~...
|
NULL
|
NULL
|
NULL
|
11065
|
|
11066
|
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
|
NULL
|
NULL
|
11066
|
|
11067
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:0986 0Today ~...
|
NULL
|
NULL
|
NULL
|
11067
|
|
11068
|
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
|
NULL
|
NULL
|
11068
|
|
11069
|
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
|
NULL
|
NULL
|
11069
|
|
11070
|
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...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
NULL
|
11070
|
|
11071
|
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
+SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:238Today ~...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
NULL
|
11071
|
|
11072
|
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...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
NULL
|
11072
|
|
11073
|
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...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
NULL
|
11073
|
|
11074
|
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
|
NULL
|
NULL
|
11074
|
|
11075
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:3186 0Today ~...
|
NULL
|
NULL
|
NULL
|
11075
|
|
11076
|
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
|
NULL
|
NULL
|
11076
|
|
11077
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:328Today ~...
|
NULL
|
NULL
|
NULL
|
11077
|
|
11078
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:348Today ~...
|
NULL
|
NULL
|
NULL
|
11078
|
|
11079
|
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
|
NULL
|
NULL
|
11079
|
|
11080
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:358Today ~...
|
NULL
|
NULL
|
NULL
|
11080
|
|
11081
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:378Today ~...
|
NULL
|
NULL
|
NULL
|
11081
|
|
11082
|
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
|
NULL
|
NULL
|
11082
|
|
11083
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:498Today ~...
|
NULL
|
NULL
|
NULL
|
11083
|
|
11084
|
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
|
NULL
|
NULL
|
11084
|
|
11085
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 49 m100% <47Tue 14 Apr 12:11:528Today ~...
|
NULL
|
NULL
|
NULL
|
11085
|
|
11086
|
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
|
NULL
|
NULL
|
11086
|
|
11087
|
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...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
NULL
|
11087
|
|
11088
|
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...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
NULL
|
11088
|
|
11089
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 48 m100% <47Tue 14 Apr 12:12:178Today ~...
|
NULL
|
NULL
|
NULL
|
11089
|
|
11090
|
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
|
NULL
|
NULL
|
11090
|
|
11091
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starredplatform-inner-teamChannels# ai-chapter# alerts# backend# confusion-clinic# curiosity_lab# engineering# frontend# general# infra-changes# jiminny-bg# platform-tickets# product launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi…..Direct messagesAneliya Angelova, ...Steliyan GeorgievAdelina Petrova, Ili.... Adelina PetrovaO. Calea Dimitravo→Search Jiminny IncAneliya Angelova, Nikolay Yankov, Steliyan GeorgievMessagesAdd canvas+Nikolay Yankov 10:45 AMпиши кат оя рьннешLukas Kovalik 10:52 AMзабавих се че ми се разбазикаха settings за средипуснах и мина и fail-наима result но e failedзначиREASON_NOT_ENOUGH_ACTIVITIESвиж дали има нещо в OD със този филтьрNikolay Yankov 11:01 AMДобреNikolay Yankov 11:39 AMя рьнни пак LukasLukas Kovalik 11:43 AMготовосьщотоCompetitive pitches беше втория нали такаNikolay Yankov 12:04 PMДа, там има 14 активитита, защо не сработи този пьт?Lukas Kovalik 12:05 PMпак изглежда sequenceгледам гоMessage Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev+Aalal]Support Daily - in 2h 48 m100% <47Tue 14 Apr 12:12:188Today ~...
|
NULL
|
NULL
|
NULL
|
11091
|
|
11092
|
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...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
NULL
|
11092
|
|
11093
|
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...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
NULL
|
11093
|