|
10952
|
217
|
28
|
2026-04-14T09:05:19.668758+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157519668_m2.jpg...
|
Slack
|
Aneliya Angelova, Nikolay Yankov, Steliyan Georgie Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev (DM) - Jiminny Inc - 1 new item - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
Directories
platform-inner-team
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_jiminny
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Steliyan Georgiev
Adelina Petrova
,
Ilian Kyuchukov
,
Steliyan Georgiev
Adelina Petrova
Galya Dimitrova
Vasil Vasilev
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Yankov
Nikolay Yankov
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Today at 10:34:10 AM
10:34 AM
не само daily но трябва да се пусне команда
Today at 10:35:08 AM
10:35
php artisan automated-reports
Nikolay Yankov
Today at 10:35:39 AM
10:35 AM
значи не създава веднага по принцип, в някакъв час на деня ли стъздава?
Lukas Kovalik
Today at 10:36:11 AM
10:36 AM
това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)
Today at 10:36:27 AM
10:36
крон го пуска през нощ
Today at 10:37:19 AM
10:37
така че мануално пусни при тестване
Today at 10:38:26 AM
10:38
ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме
Nikolay Yankov
Today at 10:41:03 AM
10:41 AM
можеш ли да я ръннеш ти командата
Lukas Kovalik
Today at 10:43:05 AM
10:43 AM
да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 10:45:52 AM
10:45 AM
пиши кат оя ръннеш
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 10:52:52 AM
10:52 AM
забавих се че ми се разбазикаха settings за среди
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:07 AM
10:53
пуснах и мина и fail-на
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:20 AM
10:53
има result но е failed
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:08 AM
10:58
значи
REASON_NOT_ENOUGH_ACTIVITIES
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:57 AM
10:58
виж дали има нещо в OD със този филтър
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:01:28 AM
11:01 AM
Добре
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:39:27 AM
11:39 AM
я рънни пак
Lukas
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 11:43:00 AM
11:43 AM
готово
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:44:24 AM
11:44
същото
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:47:25 AM
11:47
Competitive pitches беше втория нали така
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
New
Nikolay Yankov
Today at 12:04:33 PM
12:04 PM...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Jiminny Inc","depth":12,"bounds":{"left":0.23867187,"top":1.0,"width":0.0125,"height":-0.05486107},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"Jiminny (Staging)","depth":12,"bounds":{"left":0.23867187,"top":1.0,"width":0.0125,"height":-0.090972185},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Add workspaces","depth":12,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"bounds":{"left":0.26054686,"top":1.0,"width":0.0203125,"height":-0.048611164},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"bounds":{"left":0.26484376,"top":1.0,"width":0.01171875,"height":-0.08124995},"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.26054686,"top":1.0,"width":0.0203125,"height":-0.0958333},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.022265624,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.020703126,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.021484375,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.034375,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.028515626,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"frontend","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Adelina Petrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Ilian Kyuchukov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Adelina Petrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Nikolov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Nikolov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.3765625,"top":1.0,"width":0.036328126,"height":-0.079861164},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"bounds":{"left":0.3875,"top":1.0,"width":0.022265624,"height":-0.087499976},"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"bounds":{"left":0.4140625,"top":1.0,"width":0.040234376,"height":-0.079861164},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":20,"bounds":{"left":0.425,"top":1.0,"width":0.026171874,"height":-0.087499976},"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.45546874,"top":1.0,"width":0.012890625,"height":-0.079861164},"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:34:10 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:34 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"не само daily но трябва да се пусне команда","depth":25,"role_description":"text"},{"role":"AXLink","text":"Today at 10:35:08 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:35","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"php artisan automated-reports","depth":25,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:35:39 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:35 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"значи не създава веднага по принцип, в някакъв час на деня ли стъздава?","depth":25,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:36:11 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:36 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)","depth":25,"role_description":"text"},{"role":"AXLink","text":"Today at 10:36:27 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:36","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"крон го пуска през нощ","depth":25,"role_description":"text"},{"role":"AXLink","text":"Today at 10:37:19 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:37","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"така че мануално пусни при тестване","depth":25,"role_description":"text"},{"role":"AXLink","text":"Today at 10:38:26 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:38","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме","depth":25,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:41:03 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:41 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"можеш ли да я ръннеш ти командата","depth":25,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:43:05 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:43 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"да","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:45:52 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:45 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"пиши кат оя ръннеш","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:52:52 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:52 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"забавих се че ми се разбазикаха settings за среди","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:53:07 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:53","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"пуснах и мина и fail-на","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:53:20 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:53","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"има result но е failed","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:58:08 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:58","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"значи","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"REASON_NOT_ENOUGH_ACTIVITIES","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:58:57 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:58","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"виж дали има нещо в OD със този филтър","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 11:01:28 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:01 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"Добре","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 11:39:27 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:39 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"я рънни пак","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"Lukas","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 11:43:00 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:43 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"готово","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 11:44:24 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:44","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"същото","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 11:47:25 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:47","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"Competitive pitches беше втория нали така","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New","depth":22,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 12:04:33 PM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:04 PM","depth":25,"role_description":"text"}]...
|
7427672459816991510
|
-1285472192273661616
|
visual_change
|
hybrid
|
NULL
|
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
Directories
platform-inner-team
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_jiminny
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Steliyan Georgiev
Adelina Petrova
,
Ilian Kyuchukov
,
Steliyan Georgiev
Adelina Petrova
Galya Dimitrova
Vasil Vasilev
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Yankov
Nikolay Yankov
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Today at 10:34:10 AM
10:34 AM
не само daily но трябва да се пусне команда
Today at 10:35:08 AM
10:35
php artisan automated-reports
Nikolay Yankov
Today at 10:35:39 AM
10:35 AM
значи не създава веднага по принцип, в някакъв час на деня ли стъздава?
Lukas Kovalik
Today at 10:36:11 AM
10:36 AM
това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)
Today at 10:36:27 AM
10:36
крон го пуска през нощ
Today at 10:37:19 AM
10:37
така че мануално пусни при тестване
Today at 10:38:26 AM
10:38
ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме
Nikolay Yankov
Today at 10:41:03 AM
10:41 AM
можеш ли да я ръннеш ти командата
Lukas Kovalik
Today at 10:43:05 AM
10:43 AM
да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 10:45:52 AM
10:45 AM
пиши кат оя ръннеш
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 10:52:52 AM
10:52 AM
забавих се че ми се разбазикаха settings за среди
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:07 AM
10:53
пуснах и мина и fail-на
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:20 AM
10:53
има result но е failed
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:08 AM
10:58
значи
REASON_NOT_ENOUGH_ACTIVITIES
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:57 AM
10:58
виж дали има нещо в OD със този филтър
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:01:28 AM
11:01 AM
Добре
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:39:27 AM
11:39 AM
я рънни пак
Lukas
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 11:43:00 AM
11:43 AM
готово
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:44:24 AM
11:44
същото
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:47:25 AM
11:47
Competitive pitches беше втория нали така
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
New
Nikolay Yankov
Today at 12:04:33 PM
12:04 PM
FirefoxFileEditViewHistoryBookmarks)ProfilesToolsWindowHeldPlatform Sprint 1 Q2 - Platform TeaJY-20543 add AJ reports User piloZ Configure SSH access to multiple@ Console Home | Console Home | usSecurityGroup | EC2 |us-east-2JY-20543 add AJ reports User pilcSRD-6779 | JY-20632 | Unable toJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformJY-20543 add AJ reports User pilc(x) Configure SSH access to multipleCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabSaved searchesapp.staging.jiminny.com/ondemand?topic_id[]=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4You are currently impersonating Nikolay Yankov <)14 activitiesSort by: Most recent* Add RecordingA Get NotifiedleamSearch teamsiTopics: Competitors XShow internal and external activities: Show internal only *)Save Search @ Clear allHostIActivityCurrent StagestatsHostSearch team membersinise searen as particioanuParuicipantSearch team membersCustomer ®Customer or SubjectTranscript ©• Search transcript |Said byAnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreselect Ai call scoreMulomalea call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesContactActivityTypeDurationDateJiminny MSalestorce App IrainingJiminny MBekkie/ Jules - renewals and Contract..Jiminny MHandover training part 1Unknown Customer M2 8 Deal Insights playbook 2 &Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterprise MJiminny & - All-hands meeting i%TomLaveryUnknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played 1All-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...JY-18909-automated-reports-ask-iiminny = 869720)Unlikely toRenew$42,12647m90D444m90 о 3Đ0D234m00D 2$0 228.DODO17m31m43m28mD0 E1 sim25m39m33m5122ĐO D 1141m11/0/2024.2:28 PMI25/06/2024, 3:09 PM10/06/2024, 12:02 PM18/05/9014. 19.96 PMI13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMSupport Daily • in 2h 55 mTue 14 Aor 17:05:19Q InspectorFilter URLsConsoleD DebuggerN Network{) Style Editor( PerformanceELE MemoryE Storage© 99+_ Disable Cache No Throttling 50.AlIHMLeSSCtatucMethod200POs I200POST206POsIPOST200200200200200GETGETGETGETGETGET200POSTPOSTPOSTPosl200200POSTPOSTImagesMediaotheDomainA D 036719.ing...A Y 036719.ing...036/19.ing..A B 036719.ing...apo.stagino.l..A app.staging.ji...A app.staging.ji..A app.stagingji...A app.stagingji...ttind, userollot.loA app.stagingji...Ar.logr-in.comr.locl-in.comAr.logr-in.comr.locl-in.comInitiatorap1b0 310 envelodelsentry versionssentrv xe tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchap1/562/310/envelope/?sentryversion=/&sentry_ke tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchsearch?statusl|=completed&sort_by=dateHeld& * xhrrecentsaved-search" Xhiintegrationson-demand?topic_idll=e02f0932-cb76-41b6-ac +a xhrNX-0940e17authenticateA xhrYa=ponxat plattorm-staging&r=b-019d8b28-3eft-/c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c XhiTypeTransferredIsonb008843 ms500 B2 B | 43 msb00 B23 44m500 B2 B | 43 ms6.28 kB24.21 kB1537 ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 Kb 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86...| 2299 mscacheo3.12 kB126.39 KB7.89 kB6.41 kB3.48 KB2.96 kB96 B | 620 ms1359 ms|158 ms153 ms|150 ms166 msÔ 16 requests| 243.44 kB / 227.15 kB transferredFinish: 17.93s DOMContentLoaded: 42 ms load: 195 ms...
|
NULL
|
|
10953
|
217
|
29
|
2026-04-14T09:05:22.679742+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157522679_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarks)ProfilesToolsW FirefoxFileEditViewHistoryBookmarks)ProfilesToolsWindowHeldSaved searchesapp.staging.jiminny.com/ondemand?topic_id[]=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4You are currently impersonating Nikolay Yankov <)14 activitiesSort by: Most recent* Add RecordingA Get NotifiedPlatform Sprint 1 Q2 - Platform TeaJY-20543 add AJ reports User piloleamSearch teamsiTopics: Competitors XShow internal and external activities: Show internal only *)Save Search @ Clear allHostIActivityCurrent StagestatsZ Configure SSH access to multipleHost@ Console Home | Console Home | usSearch team membersiSecurityGroup | EC2 |us-east-210nise searen as particioanuJY-20543 add AJ reports User pilcSRD-6779 | JY-20632 | Unable toJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformC JY-20543 add AJ reports User pilc(x) Configure SSH access to multipleCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabParuicipantSearch team membersCustomer ®Customer or SubjectTranscript ©• Search transcript |Said byMnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreSelect Al call scoreMulomalea call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesContactActivityTypeDurationDateJiminny MSalestorce App IrainingJiminny MBekkie/ Jules - renewals and Contract..Jiminny MHandover training part 1Unknown Customer M2 8 Deal Insights playbook 2 €Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterpriseMJiminny & - All-hands meeting i%TomLaveryUnknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played MAll-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...JY-18909-automated-reports-ask-iiminny = 869720Unlikelv ToRenew$42,1264/mĐ0 D444m90 о 3Đ0D234m00D 2$0 228.DODO17m31m43m28mD0 E1 sim25m39m33m53122ĐO D 1141m11/0/2024.2:28 PMI25/06/2024, 3:09 PM10/06/2024, 12:02 PM18/05/9014. 19.96 PMI13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMSupport Daily • in 2h 55 mTue 14 Apr 12:05:22Q InspectorConsoleD DebuggerN Network{) Style Editor( PerformanceELE MemoryE Storage© 99+Filter URLs_ Disable Cache No Throttling 50.AlIHMLeSSImagesMediaotheCtatucMethod200200206PosPOSTInitiatorTypeTransferred40.80 $200200200200200200200200200POsIPOSTGETGETGETGETGETGETPOSTPOSTPOSTPOSTPOSTPoslPOSTDomainA D 036719.ing...A Y 036719.ing...036/19.ing..A B 036719.ing...apo.stagino.l..A app.staging.ji...A app.stagingji...A app.stagingji...A app.stagingji...ttind, userollot.loA app.stagingji...ap1b0 310 envelodelsentry versionssentrv xe tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchap1/562/310/envelope/?sentryversion=/&sentry_ke tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchsearch?statusl|=completed&sort_by=dateHeld& * xhrrecentsaved-search" Xhiintegrationson-demand?topic_idll=e02f0932-cb76-41b6-ac +a xhrNX-0940e17authenticateA xhrIsonAr.logr-in.comr.locl-in.comAr.logr-in.comrlocl-in.comYa=ponxat plattorm-staging&r=b-019d8b28-3eft-/c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c Xhiatrloar-in.comMa=ponxaf/o atform-staging&r=6-019d8628-3ef-7c xhnb008843 mg500 B2 B | 43 msb00 B2 B 44 mg500 B2 B | 43 ms6.28 kB24.21 kB 1537ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 kB | 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86...2298 mscacheo3.12 kB96 B | 620 ms126.39 KB7.89 kB158 ms6.41 kB348kR153 ms| 150 ms2.96 kB3.45 kB166 ms| 151 ms17 requests| 243.44 kB / 230.60 kB transferredFinish: 24.15s DOMContentLoaded: 42 ms load: 195 ms...
|
NULL
|
-6041518331789489735
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarks)ProfilesToolsW FirefoxFileEditViewHistoryBookmarks)ProfilesToolsWindowHeldSaved searchesapp.staging.jiminny.com/ondemand?topic_id[]=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4You are currently impersonating Nikolay Yankov <)14 activitiesSort by: Most recent* Add RecordingA Get NotifiedPlatform Sprint 1 Q2 - Platform TeaJY-20543 add AJ reports User piloleamSearch teamsiTopics: Competitors XShow internal and external activities: Show internal only *)Save Search @ Clear allHostIActivityCurrent StagestatsZ Configure SSH access to multipleHost@ Console Home | Console Home | usSearch team membersiSecurityGroup | EC2 |us-east-210nise searen as particioanuJY-20543 add AJ reports User pilcSRD-6779 | JY-20632 | Unable toJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformC JY-20543 add AJ reports User pilc(x) Configure SSH access to multipleCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabParuicipantSearch team membersCustomer ®Customer or SubjectTranscript ©• Search transcript |Said byMnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreSelect Al call scoreMulomalea call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesContactActivityTypeDurationDateJiminny MSalestorce App IrainingJiminny MBekkie/ Jules - renewals and Contract..Jiminny MHandover training part 1Unknown Customer M2 8 Deal Insights playbook 2 €Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterpriseMJiminny & - All-hands meeting i%TomLaveryUnknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played MAll-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...JY-18909-automated-reports-ask-iiminny = 869720Unlikelv ToRenew$42,1264/mĐ0 D444m90 о 3Đ0D234m00D 2$0 228.DODO17m31m43m28mD0 E1 sim25m39m33m53122ĐO D 1141m11/0/2024.2:28 PMI25/06/2024, 3:09 PM10/06/2024, 12:02 PM18/05/9014. 19.96 PMI13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMSupport Daily • in 2h 55 mTue 14 Apr 12:05:22Q InspectorConsoleD DebuggerN Network{) Style Editor( PerformanceELE MemoryE Storage© 99+Filter URLs_ Disable Cache No Throttling 50.AlIHMLeSSImagesMediaotheCtatucMethod200200206PosPOSTInitiatorTypeTransferred40.80 $200200200200200200200200200POsIPOSTGETGETGETGETGETGETPOSTPOSTPOSTPOSTPOSTPoslPOSTDomainA D 036719.ing...A Y 036719.ing...036/19.ing..A B 036719.ing...apo.stagino.l..A app.staging.ji...A app.stagingji...A app.stagingji...A app.stagingji...ttind, userollot.loA app.stagingji...ap1b0 310 envelodelsentry versionssentrv xe tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchap1/562/310/envelope/?sentryversion=/&sentry_ke tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchsearch?statusl|=completed&sort_by=dateHeld& * xhrrecentsaved-search" Xhiintegrationson-demand?topic_idll=e02f0932-cb76-41b6-ac +a xhrNX-0940e17authenticateA xhrIsonAr.logr-in.comr.locl-in.comAr.logr-in.comrlocl-in.comYa=ponxat plattorm-staging&r=b-019d8b28-3eft-/c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c Xhiatrloar-in.comMa=ponxaf/o atform-staging&r=6-019d8628-3ef-7c xhnb008843 mg500 B2 B | 43 msb00 B2 B 44 mg500 B2 B | 43 ms6.28 kB24.21 kB 1537ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 kB | 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86...2298 mscacheo3.12 kB96 B | 620 ms126.39 KB7.89 kB158 ms6.41 kB348kR153 ms| 150 ms2.96 kB3.45 kB166 ms| 151 ms17 requests| 243.44 kB / 230.60 kB transferredFinish: 24.15s DOMContentLoaded: 42 ms load: 195 ms...
|
10952
|
|
10954
|
217
|
30
|
2026-04-14T09:05:25.711678+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157525711_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarks)ProfilesToolsW FirefoxFileEditViewHistoryBookmarks)ProfilesToolsWindowHeldPlatform Sprint 1 Q2 - Platform TeaJY-20543 add AJ reports User piloZ Configure SSH access to multiple@ Console Home | Console Home | usSecurityGroup | EC2 |us-east-2JY-20543 add AJ reports User pilcSRD-6779 | JY-20632 | Unable toJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformJY-20543 add AJ reports User pilc(x) Configure SSH access to multipleCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabSaved searchesapp.staging.jiminny.com/ondemand?topic_id[]=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4You are currently impersonating Nikolay Yankov <)14 activitiesSort by: Most recent* Add RecordingA Get NotifiedleamSearch teamsiTopics: Competitors XShow internal and external activities: Show internal only *)Save Search @ Clear allHostIActivityCurrent StagestatsHostSearch team membersinise searen as particioanuParuicipantSearch team membersCustomer ®Customer or SubjectTranscript ©• Search transcript |Said byMnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreselect Ai call scoreMulomalea call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesContactActivityTypeDurationDateJiminny MSalestorce App IrainingJiminny MBekkie/ Jules - renewals and Contract..Jiminny MHandover training part 1Unknown Customer M2 8 Deal Insights playbook 2 &Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterpriseMJiminny & - All-hands meeting i%TomLaveryUnknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played 1All-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...JY-18909-automated-reports-ask-iiminny = 869720unlikelv toRenew$42,1264/mĐ0 D444mĐ0 D3Đ0D234m00D 2$0 228.DODO17m31m43m28mD0 E1 sim25m39m33m5122ĐO D 1141m11/0/2024.2:28 PMI25/06/2024, 3:09 PM10/06/2024, 12:02 PM18/05/9014. 19.96 PMI13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMSupport Daily • in 2h 55 mTue 14 Apr 12:05:25Q InspectorConsoleD DebuggerN Network{) Style Editor( PerformanceELE MemoryE Storage© 99+Filter URLs_ Disable Cache No Throttling 50.AlIHMLeSSImagesMediaotheCtatucMethod200200206PosPOSTInitiatorTypeTransferred40.80 $200200200200200200200200200POsIPOSTGETGETGETGETGETGETPOSTPOSTPOSTPOSTPOSTPoslPOSTDomainA D 036719.ing...A Y 036719.ing...036/19.ing..A B 036719.ing...apo.stagino.l..A app.staging.ji...A app.stagingji...A app.stagingji...A app.stagingji...ttind, userollot.loA app.stagingji...ap1b0 310 envelodelsentry versionssentrv xe tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchap1/562/310/envelope/?sentryversion=/&sentry_ke tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchsearch?statusl|=completed&sort_by=dateHeld& * xhrrecentsaved-search" Xhiintegrationson-demand?topic_idll=e02f0932-cb76-41b6-ac +a xhrNX-0940e17authenticateA xhrjsonAr.logr-in.comrlocl-in.comAr.logr-in.comrlocl-in.comYa=ponxat plattorm-staging&r=b-019d8b28-3eft-/c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c Xhiatrloar-in.comMa=ponxaf/o atform-staging&r=6-019d8628-3ef-7c xhnb008843 mg500 B2 B | 43 msb00 B2 B 44 mg500 B2 B | 43 ms6.28 kB24.21 kB 1537ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 kB | 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86...2293 mscacheo3.12 kB96 B | 620 ms126.39 KB7.89 kB158 ms6.41 kB348kR153 ms| 150 ms2.96 kB3.45 kB166 ms| 151 ms17 requests| 243.44 kB / 230.60 kB transferredFinish: 24.15s DOMContentLoaded: 42 ms load: 195 ms...
|
NULL
|
487633775529471389
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarks)ProfilesToolsW FirefoxFileEditViewHistoryBookmarks)ProfilesToolsWindowHeldPlatform Sprint 1 Q2 - Platform TeaJY-20543 add AJ reports User piloZ Configure SSH access to multiple@ Console Home | Console Home | usSecurityGroup | EC2 |us-east-2JY-20543 add AJ reports User pilcSRD-6779 | JY-20632 | Unable toJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformJY-20543 add AJ reports User pilc(x) Configure SSH access to multipleCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabSaved searchesapp.staging.jiminny.com/ondemand?topic_id[]=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4You are currently impersonating Nikolay Yankov <)14 activitiesSort by: Most recent* Add RecordingA Get NotifiedleamSearch teamsiTopics: Competitors XShow internal and external activities: Show internal only *)Save Search @ Clear allHostIActivityCurrent StagestatsHostSearch team membersinise searen as particioanuParuicipantSearch team membersCustomer ®Customer or SubjectTranscript ©• Search transcript |Said byMnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreselect Ai call scoreMulomalea call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesContactActivityTypeDurationDateJiminny MSalestorce App IrainingJiminny MBekkie/ Jules - renewals and Contract..Jiminny MHandover training part 1Unknown Customer M2 8 Deal Insights playbook 2 &Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterpriseMJiminny & - All-hands meeting i%TomLaveryUnknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played 1All-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...JY-18909-automated-reports-ask-iiminny = 869720unlikelv toRenew$42,1264/mĐ0 D444mĐ0 D3Đ0D234m00D 2$0 228.DODO17m31m43m28mD0 E1 sim25m39m33m5122ĐO D 1141m11/0/2024.2:28 PMI25/06/2024, 3:09 PM10/06/2024, 12:02 PM18/05/9014. 19.96 PMI13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMSupport Daily • in 2h 55 mTue 14 Apr 12:05:25Q InspectorConsoleD DebuggerN Network{) Style Editor( PerformanceELE MemoryE Storage© 99+Filter URLs_ Disable Cache No Throttling 50.AlIHMLeSSImagesMediaotheCtatucMethod200200206PosPOSTInitiatorTypeTransferred40.80 $200200200200200200200200200POsIPOSTGETGETGETGETGETGETPOSTPOSTPOSTPOSTPOSTPoslPOSTDomainA D 036719.ing...A Y 036719.ing...036/19.ing..A B 036719.ing...apo.stagino.l..A app.staging.ji...A app.stagingji...A app.stagingji...A app.stagingji...ttind, userollot.loA app.stagingji...ap1b0 310 envelodelsentry versionssentrv xe tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchap1/562/310/envelope/?sentryversion=/&sentry_ke tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchsearch?statusl|=completed&sort_by=dateHeld& * xhrrecentsaved-search" Xhiintegrationson-demand?topic_idll=e02f0932-cb76-41b6-ac +a xhrNX-0940e17authenticateA xhrjsonAr.logr-in.comrlocl-in.comAr.logr-in.comrlocl-in.comYa=ponxat plattorm-staging&r=b-019d8b28-3eft-/c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c Xhiatrloar-in.comMa=ponxaf/o atform-staging&r=6-019d8628-3ef-7c xhnb008843 mg500 B2 B | 43 msb00 B2 B 44 mg500 B2 B | 43 ms6.28 kB24.21 kB 1537ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 kB | 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86...2293 mscacheo3.12 kB96 B | 620 ms126.39 KB7.89 kB158 ms6.41 kB348kR153 ms| 150 ms2.96 kB3.45 kB166 ms| 151 ms17 requests| 243.44 kB / 230.60 kB transferredFinish: 24.15s DOMContentLoaded: 42 ms load: 195 ms...
|
NULL
|
|
10956
|
217
|
31
|
2026-04-14T09:05:43.910424+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157543910_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHeldSaved searches14 activitiesYou are currently impersonating Nikolay Yankov <)Sort by: Most recentPlatform Sprint 1 Q2 - Platform TealeamTopics: Competitors XShow internal and external activities: Show internal only xJY-20543 add AJ reports User piloSearch teamsiHostIActivityZ Configure SSH access to multipleHost@ Console Home | Console Home | usSearch team membersiSecurityGroup | EC2 |us-east-210Mise searen as DarticloanuJY-20543 add AJ reports User pilcSRD-6779 | JY-20632 | Unable toJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformC JY-20543 add AJ reports User pilc(x) Configure SSH access to multipleCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabParuicipantSearch team membersCustomer ®Customer or SubjectTranscript ©• Search transcript |Said byMnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreSelect Al call scoreMulomaled call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesContactActivityTypeJiminny MSalestorce App IrainingJiminny MBekkie/ Jules - renewals and Contract..Jiminny MHandover training part 1Unknown Customer M2 8 Deal Insights playbook 2 €Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterprise MJiminny & - All-hands meeting i%TomLaveryUnknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played MAll-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...JY-18909-automated-reports-ask-iiminny = 869720* Add RecordingA Get NotifiedSave Search @ Clear allCurrent Stagestats00 D 40.Đ0 D2.00D 2Duration4/m44m34mUnlikelv ToRenew$42,126$0 228.DODO17mD0D431m43m$0 92ĐOD428m51m25m39m33m53122ĐO D 1141mDate11/0/2024.2:28 PMI25/06/2024, 3:09 PM10/06/2024, 12:02 PM18/05/9014. 19.96 PMI13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMSupport Daily - in 2h 55 mTue 14 Aor 17:05:43Q InspectorFilter URLsConsoleD Debugger{) Style Editor( PerformanceELE Memory© 99+AlIHMLeSSStatus200200206200200200200200200MethodPosPOSTPOsIPOSTGETGETGETGETGETGET2002002002002001200200200200200200POSTPOSTPOSTPUSIPOSTPOSTPOSTPOSTPOSTPOSTPOSTrontsDomainA g 036719.ing...A Y 036719.ing...036/19.ing..A B 036719.ing...apo.stagino.l..A app.staging.ji...A app.staging.ji.A app.stagingji...A app.stagingji...ttind, userollot.loA app.stagingji...Ar.logr-in.comr.locl-in.comAr.logr-in.comr.locl-in.comAr.logr-in.comrlogt-in.comAr.logr-in.comAr.logr-in.com@ r.logr-in.comN NetworkE Storage_ Disable Cache No Throttling 50.ImagesMediaotheInitiatorap1b0 310 envelode/"sentry versions sentrv xe tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchap1/562/310/envelope/?sentryversion=/&sentry_ke tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchsearch?statusl|=completed&sort_by=dateHeld& * xhrrecentsaved-search" Xhiintegrationson-demand?topic_idll=e02f0932-cb76-41b6-ac +a xhrNX-0940e17authenticateA xhrYa=ponxat plattorm-staging&r=b-019d8b28-3eft-/c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c Xhii?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhrTasponxat/olattorm-staginaxr=b-01908028-3eft-/c xhni?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhrTasponxat/olattorm-staginaxr=b-01908028-3eft-/c xhnTypeTransferredisonsonjsonjsonb008843 ms500 B2 B | 43 msb00 B23 44 ms500 B2 B | 43 ms6.28 kB24.21 kB 1537 ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 kB | 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86...| 2299 mscacheo0 ms3.12 kB96 B | 620 ms126.39 KB7.89 kB6.41 kB3.48 kB2.96 kB3.45 kB3.45 kBOB29o KB2.98 kB3,40 KB|158 ms153 ms1150 ms166 ms|151 ms157 ms1155 ms159 ms176 msÓ 21 requests |243.44 KB 243.45 KB transterredFinish: 44.49 s DOMContentLoaded: 42 ms•load: 195 ms...
|
NULL
|
5072096853394830859
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHeldSaved searches14 activitiesYou are currently impersonating Nikolay Yankov <)Sort by: Most recentPlatform Sprint 1 Q2 - Platform TealeamTopics: Competitors XShow internal and external activities: Show internal only xJY-20543 add AJ reports User piloSearch teamsiHostIActivityZ Configure SSH access to multipleHost@ Console Home | Console Home | usSearch team membersiSecurityGroup | EC2 |us-east-210Mise searen as DarticloanuJY-20543 add AJ reports User pilcSRD-6779 | JY-20632 | Unable toJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformC JY-20543 add AJ reports User pilc(x) Configure SSH access to multipleCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabParuicipantSearch team membersCustomer ®Customer or SubjectTranscript ©• Search transcript |Said byMnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreSelect Al call scoreMulomaled call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesContactActivityTypeJiminny MSalestorce App IrainingJiminny MBekkie/ Jules - renewals and Contract..Jiminny MHandover training part 1Unknown Customer M2 8 Deal Insights playbook 2 €Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterprise MJiminny & - All-hands meeting i%TomLaveryUnknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played MAll-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...JY-18909-automated-reports-ask-iiminny = 869720* Add RecordingA Get NotifiedSave Search @ Clear allCurrent Stagestats00 D 40.Đ0 D2.00D 2Duration4/m44m34mUnlikelv ToRenew$42,126$0 228.DODO17mD0D431m43m$0 92ĐOD428m51m25m39m33m53122ĐO D 1141mDate11/0/2024.2:28 PMI25/06/2024, 3:09 PM10/06/2024, 12:02 PM18/05/9014. 19.96 PMI13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMSupport Daily - in 2h 55 mTue 14 Aor 17:05:43Q InspectorFilter URLsConsoleD Debugger{) Style Editor( PerformanceELE Memory© 99+AlIHMLeSSStatus200200206200200200200200200MethodPosPOSTPOsIPOSTGETGETGETGETGETGET2002002002002001200200200200200200POSTPOSTPOSTPUSIPOSTPOSTPOSTPOSTPOSTPOSTPOSTrontsDomainA g 036719.ing...A Y 036719.ing...036/19.ing..A B 036719.ing...apo.stagino.l..A app.staging.ji...A app.staging.ji.A app.stagingji...A app.stagingji...ttind, userollot.loA app.stagingji...Ar.logr-in.comr.locl-in.comAr.logr-in.comr.locl-in.comAr.logr-in.comrlogt-in.comAr.logr-in.comAr.logr-in.com@ r.logr-in.comN NetworkE Storage_ Disable Cache No Throttling 50.ImagesMediaotheInitiatorap1b0 310 envelode/"sentry versions sentrv xe tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchap1/562/310/envelope/?sentryversion=/&sentry_ke tetch/api/5627310/envelope/?sentry_version=7&sentry_ke fetchsearch?statusl|=completed&sort_by=dateHeld& * xhrrecentsaved-search" Xhiintegrationson-demand?topic_idll=e02f0932-cb76-41b6-ac +a xhrNX-0940e17authenticateA xhrYa=ponxat plattorm-staging&r=b-019d8b28-3eft-/c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c Xhii?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhrTasponxat/olattorm-staginaxr=b-01908028-3eft-/c xhni?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhrTasponxat/olattorm-staginaxr=b-01908028-3eft-/c xhnTypeTransferredisonsonjsonjsonb008843 ms500 B2 B | 43 msb00 B23 44 ms500 B2 B | 43 ms6.28 kB24.21 kB 1537 ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 kB | 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86...| 2299 mscacheo0 ms3.12 kB96 B | 620 ms126.39 KB7.89 kB6.41 kB3.48 kB2.96 kB3.45 kB3.45 kBOB29o KB2.98 kB3,40 KB|158 ms153 ms1150 ms166 ms|151 ms157 ms1155 ms159 ms176 msÓ 21 requests |243.44 KB 243.45 KB transterredFinish: 44.49 s DOMContentLoaded: 42 ms•load: 195 ms...
|
10954
|
|
10959
|
217
|
33
|
2026-04-14T09:05:48.186988+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157548186_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEoitViewHistoryBookmarksProfilesToolsWi FirefoxFileEoitViewHistoryBookmarksProfilesToolsWindowHelpapp.staging.jiminny.com/ondemand?topic_idfl=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4 JPlatform Sprint 1 Q2 - Platform Team - Scrum Board - Jira — jiminny.atlassian.net/jira/software/c/projects/JY/boards/37JY-20543 add AJ reports User pilot tracking by LakyLak • Pull Request #11932 • jiminny/app (CJ Switch to TabPlatform Sprint 1 Q2 - Platform TeaJiminny - app.staging.jiminny.com/ai-reportsJY-20543 add AJ reports User piloInbox (1,540) - [EMAIL] - Jiminny Mail - mail.google.com/mail/u/0/#inboxZ Configure SSH access to multipleCloudWatch | us-east-2 Switch to Tab@ Console Home | Console Home | usMeet - Daily - Platform - meet.google.com/mie-gawc-dsiSecurityGroup | EC2 |us-east-210AISOwikipeala - wikipedia.orgJY-20543 add AJ reports User pilcParSRD-6779 | JY-20632 | Unable to$Recent SearchesgmailTrending on GoogleJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformJY-20543 add AJ reports User pilc& Configure SSH access to multiple eCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabCusTrarман юнаитед соешу лииде• Search transcript |Said byAnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreSelect Al call scoreMulomalea call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesJY-18909-automated-reports-ask-iiminny = 8697202 8 Deal Insights playbook 2 €Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterprise MJiminny & - All-hands meeting %Unknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played MAll-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...TomLaveryUnlikely toRenew$42,12650 02$0 828DODO17m801n.31m43m$0 82ĐO D428m51m25m39m33m$1 82ĐO D 1141m18/05/9014. 19.56 PM13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMj Support Daily • in 2h 55 m200200[PHONE]00200POSTPOSTPOSTPOSTPOSTPOSTPOSTAr.logr-in.com@ r.logr-in.comAr.logr-in.comrlogt-in.comAr.logr-in.comAr.logr-in.comAr.logr-in.comi?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c Xhii?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhrTasponxat/olattorm-staginaxr=b-01908028-3eft-/c xhni?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhrTasponxat/olattorm-staginaxr=b-01908028-3eft-/c xhnjsonsonjsonjson100% C•Tue 14 Apr 12:05:47E Storage0 99+_ Disable Cache No Throttling + 50:Transferredb008843 ms500 B2 B | 43 msb00 B2 B 44 ms500 B2 B | 43 ms6.28 kB24.21 kB 1537 ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 Kb 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86... | 2299 mscacheo0 ms3.12 kB96 B|620 ms126.39 KB7.89 kB6.41 kB3.48 kB|158 ms153 ms1150 ms2.96 kB3.45 kB3.45 kBOB29o KB2.98 kB3,40 KB| 151 msI 157 ms1155 ms159 ms176 ms21 requests| 243.44 kB / 243.45 kB transferredFinish: 44.49 s DOMContentLoaded: 42 msload: 195 ms...
|
NULL
|
8099060675247356331
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEoitViewHistoryBookmarksProfilesToolsWi FirefoxFileEoitViewHistoryBookmarksProfilesToolsWindowHelpapp.staging.jiminny.com/ondemand?topic_idfl=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4 JPlatform Sprint 1 Q2 - Platform Team - Scrum Board - Jira — jiminny.atlassian.net/jira/software/c/projects/JY/boards/37JY-20543 add AJ reports User pilot tracking by LakyLak • Pull Request #11932 • jiminny/app (CJ Switch to TabPlatform Sprint 1 Q2 - Platform TeaJiminny - app.staging.jiminny.com/ai-reportsJY-20543 add AJ reports User piloInbox (1,540) - [EMAIL] - Jiminny Mail - mail.google.com/mail/u/0/#inboxZ Configure SSH access to multipleCloudWatch | us-east-2 Switch to Tab@ Console Home | Console Home | usMeet - Daily - Platform - meet.google.com/mie-gawc-dsiSecurityGroup | EC2 |us-east-210AISOwikipeala - wikipedia.orgJY-20543 add AJ reports User pilcParSRD-6779 | JY-20632 | Unable to$Recent SearchesgmailTrending on GoogleJy 19798 evaluation for ai activity8 Jiminny7 Ask Jiminny test report - 8 Aor 201Service-Desk - Queues - PlatformJY-20543 add AJ reports User pilc& Configure SSH access to multiple eCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabCusTrarман юнаитед соешу лииде• Search transcript |Said byAnyonePeriodAll timeTopicsCompetitors *)Activity typeSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreSelect Al call scoreMulomalea call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stagesJY-18909-automated-reports-ask-iiminny = 8697202 8 Deal Insights playbook 2 €Exclaimer MExclaimer handoverUnknown Customer MHow to run an Intro CallTom Lavery at Plamen enterprise MJiminny & - All-hands meeting %Unknown Customer MAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @04:01Unknown Customer played) 1Training P - Jiminny App for Salesfor..Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer played MAll-hands - Nov /thUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...TomLaveryUnlikely toRenew$42,12650 02$0 828DODO17m801n.31m43m$0 82ĐO D428m51m25m39m33m$1 82ĐO D 1141m18/05/9014. 19.56 PM13/03/2024, 11:28 AM26/02/2024, 2:30 PM16/01/2024, 11:43 AM09/01/2024, 11:45 AM28/11/2023, 11:30 AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM07/11/2023, 11:42 AM31/10/2023, 11:35 AM25/10/2023, 11:46 AMj Support Daily • in 2h 55 m200200[PHONE]00200POSTPOSTPOSTPOSTPOSTPOSTPOSTAr.logr-in.com@ r.logr-in.comAr.logr-in.comrlogt-in.comAr.logr-in.comAr.logr-in.comAr.logr-in.comi?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhra=oonxar/platrorm-stacinear=b-01500020-3e1-/c Xhii?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhrTasponxat/olattorm-staginaxr=b-01908028-3eft-/c xhni?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhrTasponxat/olattorm-staginaxr=b-01908028-3eft-/c xhnjsonsonjsonjson100% C•Tue 14 Apr 12:05:47E Storage0 99+_ Disable Cache No Throttling + 50:Transferredb008843 ms500 B2 B | 43 msb00 B2 B 44 ms500 B2 B | 43 ms6.28 kB24.21 kB 1537 ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 Kb 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86... | 2299 mscacheo0 ms3.12 kB96 B|620 ms126.39 KB7.89 kB6.41 kB3.48 kB|158 ms153 ms1150 ms2.96 kB3.45 kB3.45 kBOB29o KB2.98 kB3,40 KB| 151 msI 157 ms1155 ms159 ms176 ms21 requests| 243.44 kB / 243.45 kB transferredFinish: 44.49 s DOMContentLoaded: 42 msload: 195 ms...
|
10958
|
|
10960
|
216
|
17
|
2026-04-14T09:05:49.506742+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157549506_m1.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starred8platform-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...R. 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 GeorgievAa> 0ladolSupport Daily - in 2h 55 m100% C7Tue 14 Apr 12:05:4886 0Today ~...
|
NULL
|
3692077149034004861
|
NULL
|
visual_change
|
ocr
|
NULL
|
+SlackEDHomeDMSActivityFilesLater..•More+FileEditV +SlackEDHomeDMSActivityFilesLater..•More+FileEditViewGoHistoryWindowHelpJiminny ...# Starred8platform-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...R. 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 GeorgievAa> 0ladolSupport Daily - in 2h 55 m100% C7Tue 14 Apr 12:05:4886 0Today ~...
|
10957
|
|
10961
|
217
|
34
|
2026-04-14T09:05:54.201958+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157554201_m2.jpg...
|
Firefox
|
Jiminny — Work
|
1
|
app.staging.jiminny.com/ondemand?topic_id[]=e02f09 app.staging.jiminny.com/ondemand?topic_id[]=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Close tab
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
JY-18909-automated-reports-ask-jiminny ■ 869720
28
28
14
activities
Get Notified
Sort by Sort by: Most recent
Sort by
Sort by:
Most recent
Add Recording
common.ai-icon-alt
Topics:
Competitors
Show internal and external activities:
Show internal only
Save Search
Clear all
Saved searches Saved searches
Saved searches
Saved searches
Team
Search teams Search teams
Search teams
Search teams
Host
Search team members Search team members
Search team members
Search team members
Also search as participant
Participant
Search team members Search team members
Search team members
Search team members
Customer
Customer
Transcript
Search transcript
Select option Said by
Select option
Said by
Select option Anyone
Select option
Anyone
Period
All time
Topics
Competitors × Search topics
Competitors
×
Search topics
Activity type
Search activity types Search activity types
Search activity types
Search activity types
Duration
Min (minutes)
Max (minutes)
AI call score
Select AI call score Select AI call score
Select AI call score
Select AI call score
Automated call score
Select automated call score Select automated call score
Select automated call score
Select automated call score
Coaching score
Select coaching score Select coaching score
Select coaching score
Select coaching score
Coach
Search coaches Search coaches
Search coaches
Search coaches
Stage at call
Search stages Search stages
Search stages
Search stages
Current stage
Search stages Search stages
Search stages
Search stages
Language
Search language Search language
Search language
Search language
Playlist
Search playlists Search playlists
Search playlists
Search playlists
Pending CRM notes
Not logged to CRM
Recorded
Search recorded Search recorded
Search recorded
Search recorded
Show internal and external activities
Select option Show internal only
Select option
Show internal only
Platform
Search platforms Search platforms
Search platforms
Search platforms
Call type
Search channels Search channels
Search channels
Search channels
Outcome
Search CRM Outcome Search CRM Outcome
Search CRM Outcome
Search CRM Outcome
Deal value
Min (amount)
Max (amount)
Deal close date
All time
Deal age
0
1359d
2717d+
Talking speed
0
177 wpm
252 wpm+
Talk ratio
0%
40%
60%
100%
Patience
0s
1s
2s
3s+
Longest monologue
0
5m
10m+
Longest customer story
0
5m
10m+
Rep questions
0
25
50+
Engaging questions
0
25...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.31666666,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.50972223,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.51944447,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.5395833,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-18909-automated-reports-ask-jiminny ■ 869720","depth":9,"bounds":{"left":0.09453125,"top":0.9875,"width":0.11796875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"28","depth":12,"bounds":{"left":0.096875,"top":0.925,"width":0.01875,"height":0.030555556},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"28","depth":14,"bounds":{"left":0.10664062,"top":0.9284722,"width":0.00546875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14","depth":14,"bounds":{"left":0.2421875,"top":0.061805554,"width":0.0109375,"height":0.017361112},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activities","depth":14,"bounds":{"left":0.253125,"top":0.061805554,"width":0.031640626,"height":0.017361112},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Get Notified","depth":13,"bounds":{"left":0.55078125,"top":0.058333334,"width":0.051171876,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Sort by Sort by: Most recent","depth":13,"bounds":{"left":0.36171874,"top":0.057638887,"width":0.091796875,"height":0.025694445},"value":"Sort by Sort by: Most recent","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Sort by","depth":14,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sort by:","depth":15,"bounds":{"left":0.3660156,"top":0.06458333,"width":0.019921875,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Most recent","depth":15,"bounds":{"left":0.3859375,"top":0.06458333,"width":0.030078124,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add Recording","depth":13,"bounds":{"left":0.4910156,"top":0.058333334,"width":0.056640625,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"common.ai-icon-alt","depth":14,"bounds":{"left":0.6050781,"top":0.05625,"width":0.0140625,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Topics:","depth":15,"bounds":{"left":0.24570313,"top":0.10069445,"width":0.014453125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Competitors","depth":15,"bounds":{"left":0.26210937,"top":0.10069445,"width":0.0265625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show internal and external activities:","depth":15,"bounds":{"left":0.30546874,"top":0.10069445,"width":0.07695313,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show internal only","depth":15,"bounds":{"left":0.384375,"top":0.10069445,"width":0.0390625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save Search","depth":14,"bounds":{"left":0.440625,"top":0.09861111,"width":0.0390625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear all","depth":14,"bounds":{"left":0.48359376,"top":0.09861111,"width":0.030078124,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Saved searches Saved searches","depth":13,"bounds":{"left":0.1265625,"top":0.05486111,"width":0.095703125,"height":0.025},"value":"Saved searches Saved searches","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Saved searches","depth":15,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Saved searches","depth":16,"bounds":{"left":0.13085938,"top":0.06111111,"width":0.037109375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Team","depth":13,"bounds":{"left":0.1265625,"top":0.099305555,"width":0.012890625,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search teams Search teams","depth":12,"bounds":{"left":0.1265625,"top":0.115277775,"width":0.095703125,"height":0.025},"value":"Search teams Search teams","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search teams","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search teams","depth":14,"bounds":{"left":0.13085938,"top":0.12222222,"width":0.032421876,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Host","depth":13,"bounds":{"left":0.1265625,"top":0.15,"width":0.01171875,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search team members Search team members","depth":12,"bounds":{"left":0.1265625,"top":0.16944444,"width":0.095703125,"height":0.025},"value":"Search team members Search team members","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search team members","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search team members","depth":14,"bounds":{"left":0.13085938,"top":0.17638889,"width":0.05390625,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Also search as participant","depth":13,"bounds":{"left":0.1265625,"top":0.19930555,"width":0.062109374,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Participant","depth":13,"bounds":{"left":0.1265625,"top":0.225,"width":0.026953125,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search team members Search team members","depth":12,"bounds":{"left":0.1265625,"top":0.24097222,"width":0.095703125,"height":0.025},"value":"Search team members Search team members","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search team members","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search team members","depth":14,"bounds":{"left":0.13085938,"top":0.24791667,"width":0.05390625,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Customer","depth":13,"bounds":{"left":0.1265625,"top":0.27569443,"width":0.025390625,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Customer","depth":12,"bounds":{"left":0.14140625,"top":0.2923611,"width":0.065625,"height":0.025},"help_text":"","placeholder":"Customer or Subject","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transcript","depth":13,"bounds":{"left":0.1265625,"top":0.32777777,"width":0.02578125,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search transcript","depth":12,"bounds":{"left":0.14140625,"top":0.34791666,"width":0.065625,"height":0.025},"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Select option Said by","depth":12,"bounds":{"left":0.1265625,"top":0.37708333,"width":0.095703125,"height":0.025694445},"value":"Select option Said by","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select option","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Said by","depth":14,"bounds":{"left":0.13085938,"top":0.38402778,"width":0.0171875,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select option Anyone","depth":12,"bounds":{"left":0.1265625,"top":0.40625,"width":0.095703125,"height":0.025694445},"value":"Select option Anyone","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select option","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Anyone","depth":14,"bounds":{"left":0.13085938,"top":0.41319445,"width":0.01875,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Period","depth":13,"bounds":{"left":0.1265625,"top":0.44166666,"width":0.016015625,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"All time","depth":14,"bounds":{"left":0.13203125,"top":0.46458334,"width":0.017578125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Topics","depth":13,"bounds":{"left":0.1265625,"top":0.4923611,"width":0.015234375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Competitors × Search topics","depth":12,"bounds":{"left":0.1265625,"top":0.5083333,"width":0.095703125,"height":0.02638889},"value":"Competitors × Search topics","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Competitors","depth":15,"bounds":{"left":0.13359375,"top":0.5159722,"width":0.030859375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"×","depth":16,"bounds":{"left":0.1671875,"top":0.5152778,"width":0.003125,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search topics","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity type","depth":13,"bounds":{"left":0.1265625,"top":0.54444444,"width":0.03125,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search activity types Search activity types","depth":12,"bounds":{"left":0.1265625,"top":0.56041664,"width":0.095703125,"height":0.025},"value":"Search activity types Search activity types","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search activity types","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search activity types","depth":14,"bounds":{"left":0.13085938,"top":0.5673611,"width":0.050390624,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Duration","depth":13,"bounds":{"left":0.1265625,"top":0.5951389,"width":0.023046875,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Min (minutes)","depth":13,"bounds":{"left":0.1265625,"top":0.6125,"width":0.03359375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Max (minutes)","depth":13,"bounds":{"left":0.16875,"top":0.6125,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AI call score","depth":13,"bounds":{"left":0.1265625,"top":0.6597222,"width":0.029296875,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select AI call score Select AI call score","depth":12,"bounds":{"left":0.1265625,"top":0.67569447,"width":0.095703125,"height":0.025},"value":"Select AI call score Select AI call score","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select AI call score","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select AI call score","depth":14,"bounds":{"left":0.13085938,"top":0.6826389,"width":0.0453125,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Automated call score","depth":13,"bounds":{"left":0.1265625,"top":0.7104167,"width":0.0515625,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select automated call score Select automated call score","depth":12,"bounds":{"left":0.1265625,"top":0.7263889,"width":0.095703125,"height":0.036111113},"value":"Select automated call score Select automated call score","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select automated call score","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select automated call score","depth":14,"bounds":{"left":0.13085938,"top":0.73194444,"width":0.051953126,"height":0.025694445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Coaching score","depth":13,"bounds":{"left":0.1265625,"top":0.7722222,"width":0.037109375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select coaching score Select coaching score","depth":12,"bounds":{"left":0.1265625,"top":0.7881944,"width":0.095703125,"height":0.025},"value":"Select coaching score Select coaching score","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select coaching score","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select coaching score","depth":14,"bounds":{"left":0.13085938,"top":0.7951389,"width":0.051953126,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Coach","depth":13,"bounds":{"left":0.1265625,"top":0.8229167,"width":0.01640625,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search coaches Search coaches","depth":12,"bounds":{"left":0.1265625,"top":0.8388889,"width":0.095703125,"height":0.025},"value":"Search coaches Search coaches","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search coaches","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search coaches","depth":14,"bounds":{"left":0.13085938,"top":0.84583336,"width":0.0375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Stage at call","depth":13,"bounds":{"left":0.1265625,"top":0.8736111,"width":0.02890625,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search stages Search stages","depth":12,"bounds":{"left":0.1265625,"top":0.88958335,"width":0.095703125,"height":0.025},"value":"Search stages Search stages","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search stages","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search stages","depth":14,"bounds":{"left":0.13085938,"top":0.89652777,"width":0.033203125,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Current stage","depth":13,"bounds":{"left":0.1265625,"top":0.92430556,"width":0.03359375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search stages Search stages","depth":12,"bounds":{"left":0.1265625,"top":0.94027776,"width":0.095703125,"height":0.025},"value":"Search stages Search stages","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search stages","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search stages","depth":14,"bounds":{"left":0.13085938,"top":0.94722223,"width":0.033203125,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Language","depth":13,"bounds":{"left":0.1265625,"top":0.975,"width":0.0234375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search language Search language","depth":12,"bounds":{"left":0.1265625,"top":0.9909722,"width":0.095703125,"height":0.009027779},"value":"Search language Search language","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search language","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search language","depth":14,"bounds":{"left":0.13085938,"top":0.99791664,"width":0.03984375,"height":0.0020833611},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Playlist","depth":13,"bounds":{"left":0.1265625,"top":1.0,"width":0.01796875,"height":-0.02569449},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search playlists Search playlists","depth":12,"bounds":{"left":0.1265625,"top":1.0,"width":0.095703125,"height":-0.041666627},"value":"Search playlists Search playlists","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search playlists","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search playlists","depth":14,"bounds":{"left":0.13085938,"top":1.0,"width":0.037890624,"height":-0.048611164},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pending CRM notes","depth":13,"bounds":{"left":0.1265625,"top":1.0,"width":0.048046876,"height":-0.076388836},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Not logged to CRM","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recorded","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search recorded Search recorded","depth":12,"value":"Search recorded Search recorded","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search recorded","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search recorded","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show internal and external activities","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select option Show internal only","depth":12,"value":"Select option Show internal only","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select option","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show internal only","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Platform","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search platforms Search platforms","depth":12,"value":"Search platforms Search platforms","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search platforms","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search platforms","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Call type","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search channels Search channels","depth":12,"value":"Search channels Search channels","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search channels","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search channels","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Outcome","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search CRM Outcome Search CRM Outcome","depth":12,"value":"Search CRM Outcome Search CRM Outcome","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search CRM Outcome","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search CRM Outcome","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Deal value","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Min (amount)","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Max (amount)","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Deal close date","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"All time","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Deal age","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1359d","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2717d+","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Talking speed","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"177 wpm","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"252 wpm+","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Talk ratio","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0%","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"40%","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60%","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"100%","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Patience","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0s","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1s","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2s","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3s+","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Longest monologue","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5m","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10m+","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Longest customer story","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5m","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10m+","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rep questions","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"25","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"50+","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Engaging questions","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"25","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
1791973515577543646
|
1952676728468601034
|
visual_change
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Close tab
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
JY-18909-automated-reports-ask-jiminny ■ 869720
28
28
14
activities
Get Notified
Sort by Sort by: Most recent
Sort by
Sort by:
Most recent
Add Recording
common.ai-icon-alt
Topics:
Competitors
Show internal and external activities:
Show internal only
Save Search
Clear all
Saved searches Saved searches
Saved searches
Saved searches
Team
Search teams Search teams
Search teams
Search teams
Host
Search team members Search team members
Search team members
Search team members
Also search as participant
Participant
Search team members Search team members
Search team members
Search team members
Customer
Customer
Transcript
Search transcript
Select option Said by
Select option
Said by
Select option Anyone
Select option
Anyone
Period
All time
Topics
Competitors × Search topics
Competitors
×
Search topics
Activity type
Search activity types Search activity types
Search activity types
Search activity types
Duration
Min (minutes)
Max (minutes)
AI call score
Select AI call score Select AI call score
Select AI call score
Select AI call score
Automated call score
Select automated call score Select automated call score
Select automated call score
Select automated call score
Coaching score
Select coaching score Select coaching score
Select coaching score
Select coaching score
Coach
Search coaches Search coaches
Search coaches
Search coaches
Stage at call
Search stages Search stages
Search stages
Search stages
Current stage
Search stages Search stages
Search stages
Search stages
Language
Search language Search language
Search language
Search language
Playlist
Search playlists Search playlists
Search playlists
Search playlists
Pending CRM notes
Not logged to CRM
Recorded
Search recorded Search recorded
Search recorded
Search recorded
Show internal and external activities
Select option Show internal only
Select option
Show internal only
Platform
Search platforms Search platforms
Search platforms
Search platforms
Call type
Search channels Search channels
Search channels
Search channels
Outcome
Search CRM Outcome Search CRM Outcome
Search CRM Outcome
Search CRM Outcome
Deal value
Min (amount)
Max (amount)
Deal close date
All time
Deal age
0
1359d
2717d+
Talking speed
0
177 wpm
252 wpm+
Talk ratio
0%
40%
60%
100%
Patience
0s
1s
2s
3s+
Longest monologue
0
5m
10m+
Longest customer story
0
5m
10m+
Rep questions
0
25
50+
Engaging questions
0
25...
|
NULL
|
|
10962
|
217
|
35
|
2026-04-14T09:06:00.275271+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157560275_m2.jpg...
|
Slack
|
Aneliya Angelova, Nikolay Yankov, Steliyan Georgie Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev (DM) - Jiminny Inc - 1 new item - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
Directories
platform-inner-team
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_jiminny
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Steliyan Georgiev
Adelina Petrova
,
Ilian Kyuchukov
,
Steliyan Georgiev
Adelina Petrova
Galya Dimitrova
Vasil Vasilev
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Yankov
Nikolay Yankov
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 10:35:08 AM
10:35
php artisan automated-reports
Nikolay Yankov
Today at 10:35:39 AM
10:35 AM
значи не създава веднага по принцип, в някакъв час на деня ли стъздава?
Lukas Kovalik
Today at 10:36:11 AM
10:36 AM
това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)
Today at 10:36:27 AM
10:36
крон го пуска през нощ
Today at 10:37:19 AM
10:37
така че мануално пусни при тестване
Today at 10:38:26 AM
10:38
ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме
Nikolay Yankov
Today at 10:41:03 AM
10:41 AM
можеш ли да я ръннеш ти командата
Lukas Kovalik
Today at 10:43:05 AM
10:43 AM
да
Nikolay Yankov
Today at 10:45:52 AM
10:45 AM
пиши кат оя ръннеш
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 10:52:52 AM
10:52 AM
забавих се че ми се разбазикаха settings за среди
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:07 AM
10:53
пуснах и мина и fail-на
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:20 AM
10:53
има result но е failed
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:08 AM
10:58
значи
REASON_NOT_ENOUGH_ACTIVITIES
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:57 AM
10:58
виж дали има нещо в OD със този филтър
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:01:28 AM
11:01 AM
Добре
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:39:27 AM
11:39 AM
я рънни пак
Lukas
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 11:43:00 AM
11:43 AM
готово
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:44:24 AM
11:44
същото
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:47:25 AM
11:47
Competitive pitches беше втория нали така
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Jiminny Inc","depth":12,"bounds":{"left":0.23867187,"top":1.0,"width":0.0125,"height":-0.05486107},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"Jiminny (Staging)","depth":12,"bounds":{"left":0.23867187,"top":1.0,"width":0.0125,"height":-0.090972185},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Add workspaces","depth":12,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"bounds":{"left":0.26054686,"top":1.0,"width":0.0203125,"height":-0.048611164},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"bounds":{"left":0.26484376,"top":1.0,"width":0.01171875,"height":-0.08124995},"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.26054686,"top":1.0,"width":0.0203125,"height":-0.0958333},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.022265624,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.020703126,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.021484375,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.034375,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"bounds":{"left":0.3,"top":1.0,"width":0.028515626,"height":-0.079861164},"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"frontend","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Adelina Petrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Ilian Kyuchukov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Adelina Petrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Nikolov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Nikolov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.3765625,"top":1.0,"width":0.036328126,"height":-0.079861164},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"bounds":{"left":0.3875,"top":1.0,"width":0.022265624,"height":-0.087499976},"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"bounds":{"left":0.4140625,"top":1.0,"width":0.040234376,"height":-0.079861164},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":20,"bounds":{"left":0.425,"top":1.0,"width":0.026171874,"height":-0.087499976},"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.45546874,"top":1.0,"width":0.012890625,"height":-0.079861164},"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:35:08 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:35","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"php artisan automated-reports","depth":25,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:35:39 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:35 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"значи не създава веднага по принцип, в някакъв час на деня ли стъздава?","depth":25,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:36:11 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:36 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)","depth":25,"role_description":"text"},{"role":"AXLink","text":"Today at 10:36:27 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:36","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"крон го пуска през нощ","depth":25,"role_description":"text"},{"role":"AXLink","text":"Today at 10:37:19 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:37","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"така че мануално пусни при тестване","depth":25,"role_description":"text"},{"role":"AXLink","text":"Today at 10:38:26 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:38","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме","depth":25,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:41:03 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:41 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"можеш ли да я ръннеш ти командата","depth":25,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:43:05 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:43 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"да","depth":25,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:45:52 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:45 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"пиши кат оя ръннеш","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 10:52:52 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:52 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"забавих се че ми се разбазикаха settings за среди","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:53:07 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:53","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"пуснах и мина и fail-на","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:53:20 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:53","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"има result но е failed","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:58:08 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:58","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"значи","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"REASON_NOT_ENOUGH_ACTIVITIES","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:58:57 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:58","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"виж дали има нещо в OD със този филтър","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 11:01:28 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:01 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"Добре","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 11:39:27 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:39 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"я рънни пак","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"Lukas","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"role_description":"text"},{"role":"AXLink","text":"Today at 11:43:00 AM","depth":24,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:43 AM","depth":25,"role_description":"text"},{"role":"AXStaticText","text":"готово","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 11:44:24 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:44","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"същото","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 11:47:25 AM","depth":25,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:47","depth":26,"role_description":"text"},{"role":"AXStaticText","text":"Competitive pitches беше втория нали така","depth":25,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
5224298373417127386
|
-1284909242320238256
|
visual_change
|
hybrid
|
NULL
|
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
Directories
platform-inner-team
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_jiminny
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Steliyan Georgiev
Adelina Petrova
,
Ilian Kyuchukov
,
Steliyan Georgiev
Adelina Petrova
Galya Dimitrova
Vasil Vasilev
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Yankov
Nikolay Yankov
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 10:35:08 AM
10:35
php artisan automated-reports
Nikolay Yankov
Today at 10:35:39 AM
10:35 AM
значи не създава веднага по принцип, в някакъв час на деня ли стъздава?
Lukas Kovalik
Today at 10:36:11 AM
10:36 AM
това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)
Today at 10:36:27 AM
10:36
крон го пуска през нощ
Today at 10:37:19 AM
10:37
така че мануално пусни при тестване
Today at 10:38:26 AM
10:38
ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме
Nikolay Yankov
Today at 10:41:03 AM
10:41 AM
можеш ли да я ръннеш ти командата
Lukas Kovalik
Today at 10:43:05 AM
10:43 AM
да
Nikolay Yankov
Today at 10:45:52 AM
10:45 AM
пиши кат оя ръннеш
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 10:52:52 AM
10:52 AM
забавих се че ми се разбазикаха settings за среди
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:07 AM
10:53
пуснах и мина и fail-на
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:20 AM
10:53
има result но е failed
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:08 AM
10:58
значи
REASON_NOT_ENOUGH_ACTIVITIES
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:57 AM
10:58
виж дали има нещо в OD със този филтър
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:01:28 AM
11:01 AM
Добре
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:39:27 AM
11:39 AM
я рънни пак
Lukas
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 11:43:00 AM
11:43 AM
готово
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:44:24 AM
11:44
същото
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:47:25 AM
11:47
Competitive pitches беше втория нали така
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
FirefoxFileEditViewHistoryBookmarks)ProfilesToolsWindowHelpSaved searchesapp.staging.jiminny.com/ondemand?topic_id[]=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=4You are currently impersonating Nikolay Yankov <)14 activitiesSort by: Most recentPlatform Sprint 1 Q2 - Platform TeaJY-20543 add AJ reports User piloleamSearch teamsiZ Configure SSH access to multipleHost@ Console Home | Console Home | usSearch team membersiSecurityGroup | EC2 |us-east-2niso searen as particioantJY-20543 add AJ reports User pilcParuicipantSRD-6779 | JY-20632 | Unable to$searcn leam memdersJy 19798 evaluation for ai activity& JiminnyAsk Jiminny test report - 8 Aor 20Service-Desk - Queues - PlatformC JY-20543 add AJ reports User pilc& Configure SSH access to multiple eCa CloudWatch | us-east-2New TabCa CloudWatch | us-east-2+ New TabCustomer ®Customer or SubjectTranscript ©• Search transcript |Said byAnyonePeriodAll timeTopicsCompetiActivity typlSearch activity typesDuration ©Min (minutes)Max (minutes)Al call scoreselect Ai call scoreMulomalea call scoreSelect automated calliCoaching scoreSelect coaching scoreCoach ®Search coaches.Stage at callSearch stagesCurrent stageSearch stages+ Add RecordingTopics: Competitors XShow internal and external activities: Show internal only X)Save SearchClear allHostIActivityContactActivityCurrent StagestatsTypeJWJiminny MSalestorce App IrainingFirefoxJY-18909-automated-reports-ask-iiminny = 869720Jiminny MBekkie/ Jules - renewals and Contract…Jiminny MHandover training part 1Unknown Customer Md 6 Deal Insights playbook d $Exclaimer MExclaimer handoverPSAll -hands Jan 9thUnknown Customer MNotetaker added on 11-28-23 @ 04:01Unknown Customer played MTraining ? - Jiminny App for Salesfor….8)Unknown Customer MAll-hands - Thank Yous, What Went, L...Unknown Customer (played MAll-hands - Nov /thiUnknown Customer 1All Hands - October 31st ©Unknown Customer MDeal Insights Referesher/Training w/T...unlikelv toRenew$42,126$I00 D 4I 19 0D300D 2$0 228.DO DO0D6$0 92•0 D 42 1ĐOD7{0 83Đ0 D350920 D4$092Đ0 D1S1 c 2D11Duration4/m44m34m17m43m28m51m25m39m41mA Get NotifiedDate11/0/2024.2:28 PMI25/06/2024, 3:09 PM10/06/2024, 12:02 PM18/05/9014. 19.96 PMI13/03/2024, 11:28 AMSupport Daily • in 2h 55 m(БГ)Tue 14 Apr 12:05:59Q InspectorP Filter URLsConsoleD DebuggerN Network{} Style Editor( PerformanceO: Memory© 99+ImagesMediaotheStatus200200206200200200200200200200200200200200200200200200200HlMLOSSMethodPosPOSTPOSTPOSTGETGETGETGETGETGETPOSTPOSTPOSTPoslPOSTPOSTPOSTPOSTPOSTDomainInitiatorA D 036719.ing...ao1b02S0envelode/"sentry versionssentry xe tetchA Y 036719.ing.../api/5627310/envelope/?sentry_version=7&sentry_ke fetch036/19.ing..ap1/562/310/envelope/?sentryversion=/&sentry_ke tetchA B 036719.ing.../api/5627310/envelope/?sentry_version=7&sentry_ke fetchapo.stagino.l..search?statusl|=completed&sort_by=dateHeld& * xhrA app.staging.ji...recentA app. staging.j...saved-searchA xhrA app.stagingji...integrationsA app.stagingji...on-demand?topic_idll=e02f0932-cb76-41b6-ac +a xhrttind, userollot.loNX-0940e17A app.stagingji...authenticateA xhrYa=ponxat plattorm-staging&r=b-019d8b28-3eft-/c xhrAr.logr-in.comr.locl-in.comAr.logr-in.comrlocl-in.comAr.logr-in.comrlogt-in.comAr.logr-in.comi?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/platform-staging&r=6-019d8b28-3eff-7c xhri?a=ponxaf/olatform-stagina&r=6-019d8b28-3eff-7c xhnE Storage_ Disable Cache No Throttling + 50:TypeTransferredjsonIsonb008843 ms500 B2 B | 43 msb00 B2 B 44 ms500 B2 B | 43 ms6.28 kB24.21 kB | 1537 ms5.65 kB15.26 kB | 211 ms3.62 kB1.42 kB | 1508 ms3.83 kB5.53 kB | 1253 ms55.53 kB 196.86...| 2299 mscacheo3.12 kB96 B | 620 ms126.39 KB7.89 kB6.41 kB3.48 kB|158 ms153 ms| 150 ms2.96 kB3.45 kB3.45 kB2.95 kBOBOBOB2.98 kB3.46 kBо в3.47 kB| 151 ms157 ms1155 ms| 159 ms| 176 ms| 155 ms3.47 kB2.96 kB| 148 ms09/01/2024, 11:45 AM9911099 11•0AM22/11/2023, 11:56 AM14/11/2023, 11:27 AM0/119O/3.11:42 AMI31/10/2023, 11:35 AM25/10/2023, 11:46 AM24 requests243.44 KB 253.36 KB transterredFinish: 1.01 min DOMContentLoaded: 42 ms load: 195 ms...
|
10961
|
|
10963
|
216
|
18
|
2026-04-14T09:06:01.489666+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157561489_m1.jpg...
|
Slack
|
Aneliya Angelova, Nikolay Yankov, Steliyan Georgie Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev (DM) - Jiminny Inc - 1 new item - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
Directories
platform-inner-team
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_jiminny
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Steliyan Georgiev
Adelina Petrova
,
Ilian Kyuchukov
,
Steliyan Georgiev
Adelina Petrova
Galya Dimitrova
Vasil Vasilev
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Yankov
Nikolay Yankov
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 10:35:08 AM
10:35
php artisan automated-reports
Nikolay Yankov
Today at 10:35:39 AM
10:35 AM
значи не създава веднага по принцип, в някакъв час на деня ли стъздава?
Lukas Kovalik
Today at 10:36:11 AM
10:36 AM
това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)
Today at 10:36:27 AM
10:36
крон го пуска през нощ
Today at 10:37:19 AM
10:37
така че мануално пусни при тестване
Today at 10:38:26 AM
10:38
ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме
Nikolay Yankov
Today at 10:41:03 AM
10:41 AM
можеш ли да я ръннеш ти командата
Lukas Kovalik
Today at 10:43:05 AM
10:43 AM
да
Nikolay Yankov
Today at 10:45:52 AM
10:45 AM
пиши кат оя ръннеш
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 10:52:52 AM
10:52 AM
забавих се че ми се разбазикаха settings за среди
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:07 AM
10:53
пуснах и мина и fail-на
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:20 AM
10:53
има result но е failed
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:08 AM
10:58
значи
REASON_NOT_ENOUGH_ACTIVITIES
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:57 AM
10:58
виж дали има нещо в OD със този филтър
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:01:28 AM
11:01 AM
Добре
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:39:27 AM
11:39 AM
я рънни пак
Lukas
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 11:43:00 AM
11:43 AM
готово
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:44:24 AM
11:44
същото
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:47:25 AM
11:47
Competitive pitches беше втория нали така
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
New
Nikolay Yankov
Today at 12:04:33 PM
12:04 PM
Да, там има 14 активитита, защо не сработи този път?
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 12:05:31 PM...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Jiminny Inc","depth":12,"bounds":{"left":0.009722223,"top":0.08777778,"width":0.022222223,"height":0.035555556},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"Jiminny (Staging)","depth":12,"bounds":{"left":0.009722223,"top":0.14555556,"width":0.022222223,"height":0.035555556},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Add workspaces","depth":12,"bounds":{"left":0.009722223,"top":0.20333333,"width":0.022222223,"height":0.035555556},"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"bounds":{"left":0.048611112,"top":0.07777778,"width":0.036111113,"height":0.075555556},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"bounds":{"left":0.05625,"top":0.13,"width":0.020833334,"height":0.015555556},"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.048611112,"top":0.15333334,"width":0.036111113,"height":0.075555556},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"bounds":{"left":0.058333334,"top":0.20555556,"width":0.016666668,"height":0.015555556},"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"bounds":{"left":0.048611112,"top":0.22888888,"width":0.036111113,"height":0.075555556},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"bounds":{"left":0.05277778,"top":0.28111112,"width":0.027083334,"height":0.015555556},"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"bounds":{"left":0.048611112,"top":0.30444443,"width":0.036111113,"height":0.075555556},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"bounds":{"left":0.058333334,"top":0.35666665,"width":0.015972223,"height":0.015555556},"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"bounds":{"left":0.048611112,"top":0.38,"width":0.036111113,"height":0.075555556},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"bounds":{"left":0.057638887,"top":0.43222222,"width":0.018055556,"height":0.015555556},"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"bounds":{"left":0.048611112,"top":0.45555556,"width":0.036111113,"height":0.075555556},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"bounds":{"left":0.056944445,"top":0.50777775,"width":0.01875,"height":0.015555556},"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"bounds":{"left":0.11875,"top":0.12777779,"width":0.039583333,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"bounds":{"left":0.11875,"top":0.12777779,"width":0.036805555,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"bounds":{"left":0.11875,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"bounds":{"left":0.11875,"top":0.12777779,"width":0.06111111,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"bounds":{"left":0.11875,"top":0.12777779,"width":0.050694443,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"bounds":{"left":0.12986112,"top":0.18222222,"width":0.093055554,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"bounds":{"left":0.12986112,"top":0.25555557,"width":0.046527777,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"bounds":{"left":0.12986112,"top":0.28666666,"width":0.025694445,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"bounds":{"left":0.12986112,"top":0.31777778,"width":0.038194444,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"bounds":{"left":0.12986112,"top":0.34888887,"width":0.072222225,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"bounds":{"left":0.12986112,"top":0.38,"width":0.057638887,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"bounds":{"left":0.12986112,"top":0.41111112,"width":0.054166667,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"frontend","depth":23,"bounds":{"left":0.12986112,"top":0.4422222,"width":0.04027778,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"bounds":{"left":0.12986112,"top":0.47333333,"width":0.034027778,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"infra-changes","depth":23,"bounds":{"left":0.12986112,"top":0.5044444,"width":0.061805554,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"bounds":{"left":0.12986112,"top":0.53555554,"width":0.048611112,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"bounds":{"left":0.12986112,"top":0.56666666,"width":0.072916664,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"bounds":{"left":0.12986112,"top":0.5977778,"width":0.08055556,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"bounds":{"left":0.12986112,"top":0.6288889,"width":0.035416666,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"bounds":{"left":0.12986112,"top":0.66,"width":0.038194444,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"bounds":{"left":0.12986112,"top":0.6911111,"width":0.05138889,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"bounds":{"left":0.12986112,"top":0.7222222,"width":0.036111113,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"bounds":{"left":0.12986112,"top":0.75333333,"width":0.05138889,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"bounds":{"left":0.12986112,"top":0.78444445,"width":0.094444446,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.12986112,"top":0.8577778,"width":0.07847222,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"bounds":{"left":0.20833333,"top":0.8577778,"width":0.013194445,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"bounds":{"left":0.21319444,"top":0.8577778,"width":0.029861111,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"bounds":{"left":0.12986112,"top":0.8888889,"width":0.07986111,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"Adelina Petrova","depth":23,"bounds":{"left":0.12986112,"top":0.92,"width":0.072222225,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"bounds":{"left":0.2013889,"top":0.92,"width":0.0055555557,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"Ilian Kyuchukov","depth":23,"bounds":{"left":0.20694445,"top":0.92,"width":0.015972223,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Adelina Petrova","depth":23,"bounds":{"left":0.12986112,"top":0.95111114,"width":0.072222225,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"bounds":{"left":0.12986112,"top":0.9822222,"width":0.07361111,"height":0.012222222},"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Nikolov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Nikolov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.25486112,"top":0.12777779,"width":0.06458333,"height":0.04222222},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"bounds":{"left":0.27430555,"top":0.14,"width":0.039583333,"height":0.017777778},"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"bounds":{"left":0.32152778,"top":0.12777779,"width":0.07152778,"height":0.04222222},"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":20,"bounds":{"left":0.34097221,"top":0.14,"width":0.046527777,"height":0.017777778},"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.3951389,"top":0.12777779,"width":0.022916667,"height":0.04222222},"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"bounds":{"left":0.59375,"top":0.17666666,"width":0.05277778,"height":0.031111112},"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:35:08 AM","depth":25,"bounds":{"left":0.2611111,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:35","depth":26,"bounds":{"left":0.2611111,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"php artisan automated-reports","depth":25,"bounds":{"left":0.29444444,"top":0.16111112,"width":0.14513889,"height":0.0011111111},"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.072222225,"height":0.0011111111},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35972223,"top":0.16111112,"width":0.00625,"height":0.0011111111},"role_description":"text"},{"role":"AXLink","text":"Today at 10:35:39 AM","depth":24,"bounds":{"left":0.36527777,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:35 AM","depth":25,"bounds":{"left":0.36527777,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"значи не създава веднага по принцип, в някакъв час на деня ли стъздава?","depth":25,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.35416666,"height":0.0011111111},"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35277778,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"role_description":"text"},{"role":"AXLink","text":"Today at 10:36:11 AM","depth":24,"bounds":{"left":0.35833332,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:36 AM","depth":25,"bounds":{"left":0.35833332,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)","depth":25,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.4451389,"height":0.0011111111},"role_description":"text"},{"role":"AXLink","text":"Today at 10:36:27 AM","depth":25,"bounds":{"left":0.2611111,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:36","depth":26,"bounds":{"left":0.2611111,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"крон го пуска през нощ","depth":25,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.11319444,"height":0.0011111111},"role_description":"text"},{"role":"AXLink","text":"Today at 10:37:19 AM","depth":25,"bounds":{"left":0.2611111,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:37","depth":26,"bounds":{"left":0.2611111,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"така че мануално пусни при тестване","depth":25,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.18055555,"height":0.0011111111},"role_description":"text"},{"role":"AXLink","text":"Today at 10:38:26 AM","depth":25,"bounds":{"left":0.2611111,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:38","depth":26,"bounds":{"left":0.2611111,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме","depth":25,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.6423611,"height":0.0011111111},"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.072222225,"height":0.0011111111},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35972223,"top":0.16111112,"width":0.00625,"height":0.0011111111},"role_description":"text"},{"role":"AXLink","text":"Today at 10:41:03 AM","depth":24,"bounds":{"left":0.36527777,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:41 AM","depth":25,"bounds":{"left":0.36527777,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"можеш ли да я ръннеш ти командата","depth":25,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.18055555,"height":0.0011111111},"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35277778,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"role_description":"text"},{"role":"AXLink","text":"Today at 10:43:05 AM","depth":24,"bounds":{"left":0.35833332,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:43 AM","depth":25,"bounds":{"left":0.35833332,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"role_description":"text"},{"role":"AXStaticText","text":"да","depth":25,"bounds":{"left":0.28819445,"top":0.16111112,"width":0.011805556,"height":0.006666667},"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"bounds":{"left":0.28819445,"top":0.17888889,"width":0.072222225,"height":0.024444444},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35972223,"top":0.18111111,"width":0.00625,"height":0.02},"role_description":"text"},{"role":"AXLink","text":"Today at 10:45:52 AM","depth":24,"bounds":{"left":0.36527777,"top":0.18444444,"width":0.036805555,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:45 AM","depth":25,"bounds":{"left":0.36527777,"top":0.18444444,"width":0.036805555,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"пиши кат оя ръннеш","depth":25,"bounds":{"left":0.28819445,"top":0.20555556,"width":0.099305555,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.28819445,"top":0.23666666,"width":0.06458333,"height":0.024444444},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35277778,"top":0.23888889,"width":0.0055555557,"height":0.02},"role_description":"text"},{"role":"AXLink","text":"Today at 10:52:52 AM","depth":24,"bounds":{"left":0.35833332,"top":0.24222222,"width":0.036805555,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:52 AM","depth":25,"bounds":{"left":0.35833332,"top":0.24222222,"width":0.036805555,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"забавих се че ми се разбазикаха settings за среди","depth":25,"bounds":{"left":0.28819445,"top":0.26333332,"width":0.23680556,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:53:07 AM","depth":25,"bounds":{"left":0.2611111,"top":0.3,"width":0.021527778,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:53","depth":26,"bounds":{"left":0.2611111,"top":0.3,"width":0.021527778,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"пуснах и мина и fail-на","depth":25,"bounds":{"left":0.28819445,"top":0.29666665,"width":0.108333334,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:53:20 AM","depth":25,"bounds":{"left":0.2611111,"top":0.33333334,"width":0.021527778,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:53","depth":26,"bounds":{"left":0.2611111,"top":0.33333334,"width":0.021527778,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"има result но е failed","depth":25,"bounds":{"left":0.28819445,"top":0.33,"width":0.097222224,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:58:08 AM","depth":25,"bounds":{"left":0.2611111,"top":0.36666667,"width":0.021527778,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:58","depth":26,"bounds":{"left":0.2611111,"top":0.36666667,"width":0.021527778,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"значи","depth":25,"bounds":{"left":0.28819445,"top":0.36333334,"width":0.027083334,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"REASON_NOT_ENOUGH_ACTIVITIES","depth":25,"bounds":{"left":0.29444444,"top":0.40222222,"width":0.14027777,"height":0.016666668},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 10:58:57 AM","depth":25,"bounds":{"left":0.2611111,"top":0.4488889,"width":0.021527778,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:58","depth":26,"bounds":{"left":0.2611111,"top":0.4488889,"width":0.021527778,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"виж дали има нещо в OD със този филтър","depth":25,"bounds":{"left":0.28819445,"top":0.44555557,"width":0.2048611,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"bounds":{"left":0.28819445,"top":0.47666666,"width":0.072222225,"height":0.024444444},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35972223,"top":0.4788889,"width":0.00625,"height":0.02},"role_description":"text"},{"role":"AXLink","text":"Today at 11:01:28 AM","depth":24,"bounds":{"left":0.36527777,"top":0.48222223,"width":0.036805555,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:01 AM","depth":25,"bounds":{"left":0.36527777,"top":0.48222223,"width":0.036805555,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"Добре","depth":25,"bounds":{"left":0.28819445,"top":0.50333333,"width":0.03125,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"bounds":{"left":0.28819445,"top":0.53444445,"width":0.072222225,"height":0.024444444},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35972223,"top":0.5366667,"width":0.00625,"height":0.02},"role_description":"text"},{"role":"AXLink","text":"Today at 11:39:27 AM","depth":24,"bounds":{"left":0.36527777,"top":0.54,"width":0.036805555,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:39 AM","depth":25,"bounds":{"left":0.36527777,"top":0.54,"width":0.036805555,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"я рънни пак","depth":25,"bounds":{"left":0.28819445,"top":0.5611111,"width":0.059722222,"height":0.02},"role_description":"text"},{"role":"AXStaticText","text":"Lukas","depth":25,"bounds":{"left":0.3472222,"top":0.5611111,"width":0.02638889,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.28819445,"top":0.5922222,"width":0.06458333,"height":0.024444444},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35277778,"top":0.59444445,"width":0.0055555557,"height":0.02},"role_description":"text"},{"role":"AXLink","text":"Today at 11:43:00 AM","depth":24,"bounds":{"left":0.35833332,"top":0.5977778,"width":0.036805555,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:43 AM","depth":25,"bounds":{"left":0.35833332,"top":0.5977778,"width":0.036805555,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"готово","depth":25,"bounds":{"left":0.28819445,"top":0.6188889,"width":0.031944446,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 11:44:24 AM","depth":25,"bounds":{"left":0.2611111,"top":0.65555555,"width":0.021527778,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:44","depth":26,"bounds":{"left":0.2611111,"top":0.65555555,"width":0.021527778,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"същото","depth":25,"bounds":{"left":0.28819445,"top":0.6522222,"width":0.036805555,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 11:47:25 AM","depth":25,"bounds":{"left":0.2611111,"top":0.6888889,"width":0.021527778,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"11:47","depth":26,"bounds":{"left":0.2611111,"top":0.6888889,"width":0.021527778,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"Competitive pitches беше втория нали така","depth":25,"bounds":{"left":0.28819445,"top":0.6855556,"width":0.20555556,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New","depth":22,"bounds":{"left":0.96458334,"top":0.7033333,"width":0.01875,"height":0.017777778},"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"bounds":{"left":0.28819445,"top":0.71666664,"width":0.072222225,"height":0.024444444},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35972223,"top":0.7188889,"width":0.00625,"height":0.02},"role_description":"text"},{"role":"AXLink","text":"Today at 12:04:33 PM","depth":24,"bounds":{"left":0.36527777,"top":0.7222222,"width":0.036805555,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:04 PM","depth":25,"bounds":{"left":0.36527777,"top":0.7222222,"width":0.036805555,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"Да, там има 14 активитита, защо не сработи този път?","depth":25,"bounds":{"left":0.28819445,"top":0.74333334,"width":0.26319444,"height":0.02},"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.28819445,"top":0.77444446,"width":0.06458333,"height":0.024444444},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.35277778,"top":0.77666664,"width":0.0055555557,"height":0.02},"role_description":"text"},{"role":"AXLink","text":"Today at 12:05:31 PM","depth":24,"bounds":{"left":0.35833332,"top":0.78,"width":0.036111113,"height":0.016666668},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
816995233549934699
|
-1285472192273661616
|
visual_change
|
hybrid
|
NULL
|
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Jiminny Inc
Jiminny (Staging)
Add workspaces
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
Directories
platform-inner-team
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_jiminny
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Steliyan Georgiev
Adelina Petrova
,
Ilian Kyuchukov
,
Steliyan Georgiev
Adelina Petrova
Galya Dimitrova
Vasil Vasilev
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Nikolov
Galya Dimitrova
,
Nikolay Yankov
Nikolay Yankov
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Today at 10:35:08 AM
10:35
php artisan automated-reports
Nikolay Yankov
Today at 10:35:39 AM
10:35 AM
значи не създава веднага по принцип, в някакъв час на деня ли стъздава?
Lukas Kovalik
Today at 10:36:11 AM
10:36 AM
това ще гледа всичко applicable за днес (ако не понедлник или начало на месец е само daily)
Today at 10:36:27 AM
10:36
крон го пуска през нощ
Today at 10:37:19 AM
10:37
така че мануално пусни при тестване
Today at 10:38:26 AM
10:38
ако трябва да тестваме други репорти може да променя команда за тестване да приема параметър за report template и д си пускаме определен когато тестваме
Nikolay Yankov
Today at 10:41:03 AM
10:41 AM
можеш ли да я ръннеш ти командата
Lukas Kovalik
Today at 10:43:05 AM
10:43 AM
да
Nikolay Yankov
Today at 10:45:52 AM
10:45 AM
пиши кат оя ръннеш
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 10:52:52 AM
10:52 AM
забавих се че ми се разбазикаха settings за среди
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:07 AM
10:53
пуснах и мина и fail-на
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:53:20 AM
10:53
има result но е failed
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:08 AM
10:58
значи
REASON_NOT_ENOUGH_ACTIVITIES
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 10:58:57 AM
10:58
виж дали има нещо в OD със този филтър
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:01:28 AM
11:01 AM
Добре
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 11:39:27 AM
11:39 AM
я рънни пак
Lukas
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 11:43:00 AM
11:43 AM
готово
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:44:24 AM
11:44
същото
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 11:47:25 AM
11:47
Competitive pitches беше втория нали така
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
New
Nikolay Yankov
Today at 12:04:33 PM
12:04 PM
Да, там има 14 активитита, защо не сработи този път?
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 12:05:31 PM
+SlackEDHomeDMsActivityFilesLater..•More+FileEditViewGoHistoryWindowHelp‹ >0 llJiminny ...# Starred8platform-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...R. Adelina PetrovaO. Cala 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 GeorgievAa§ Support Daily • in 2h 54 m100% <7*Tue 14 Apr 12:06:0184Today ~New...
|
NULL
|
|
10965
|
217
|
37
|
2026-04-14T09:06:03.305510+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157563305_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityServiceTest.ph faVsco.js – AskJiminnyReportActivityServiceTest.php...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.76171875,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.7796875,"top":0.017361112,"width":0.12109375,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","depth":4,"bounds":{"left":0.490625,"top":0.12777779,"width":0.3347656,"height":0.8722222},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.4234375,"top":0.1736111,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.43710938,"top":0.1736111,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.4484375,"top":0.17222223,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.45703125,"top":0.17222223,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"bounds":{"left":0.15234375,"top":0.0,"width":0.39882812,"height":1.0},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8932460332387265586
|
-8276790037575160524
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $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...
|
10964
|
|
10969
|
217
|
39
|
2026-04-14T09:06:06.926749+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157566926_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodelaraveRetactonTool PhpStormFileFditViewNavigateCodelaraveRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.phpJiminnybeouecommana.ongAutomatedReportsCommand.php= custom.lo9= laravel.logL SF (iminny@localhostD UnitActionsComponentConfigurationM ConsoleM ContractsM7 DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTest→I Listeners→]Mal> MModelsM Notifications› M ObserversPoliciesProvidersRepositories> D Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedRenonAulomaleakeporissendcommand.ongC AddLayoutEntities.phpC Team.phpC) AutomatedReportsRepository.php XHs local liminnyalocalnostconsole PRODL console [EUl© AutomatedReportsService.php© CreateHeldActivityEvent.phpe) TrackProviderinstallled-vent.ono¿ consoe STAGING© AskJiminnyReportActivityService.phpC ActivityLogged.php© AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.phpC RequestGenerateAskJiminnyReportJob.phpC RequestGenerateReportJob.phpsrong© AutomatedReportResult.php© AutomatedReport.phpdeclare(strict_types=1);class AutomatedReportsrepos1toryA15 V4namesnace liests Unit Services Klosk AutomatedRenorts:* dreturn AutomatedReportuse...public function create(array $data): AutomatedReport...class AskaminnyReportActivityServicelest extends TestCase* Find an automated report by UUID*dparam string suuld25* drecurn Aurondredkeoorcnuupublic function findByUuid(string Suuid): ?AutomatedReportreturn AutomatedReport::where('uuid', AutomatedReport:: to0ptimized(Suuid))->firstO:2729 GT>Tusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReportif (is numeric(sidorluid)) "return AutomatedReport::where('uvid', AutomatedReport::to0ptimized(Sid0rUuid))->firstO;* Retrieve all standard (non-Ask Jiminny) automated reports.100 M ›* dparam string ssortcolumnThe column to sort by. Allowed values: 'created_by', 'created_at'. 118 %% >* @param string $sortDirection The sort direction. Allowed values:"asc, "desc". veraults to "des-oe157 % >* drerurn couuectonsaurondredredor*/12 usagespublic function getAllStandardReportsstring SsortColumn ="created at',string SsortDirection = 'desc': Collection 1...185 VA N206 D >-2242251*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam usersuserIne user wnose reporus to retrieve.*oparan scring esortho lunnThe column to sort by. Allowed values: 'created_by', 'created_at'. 232* Oparam string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'dez 233* dreturn Collection<AutomatedReport>22923023123425525614 usagesWinasun ch00 2.12.21: A new version is avallable. View chancelod loday 10:33.ls usadeslo usaces1o usages9 usagesprivate ActivitySearch&Mock0bject $activitySearch;private ElasticActivityRepository&Mock0bject SelasticRepository:private LoggerinterfacexMock0bject sloggerprivate AskJ1minnykeporcAculVityservice sservice;protected function setUp: voidt...hIl usagesprivate function makeFilter(string $key. ?string $value): SearchFilto usaeesprivate function makeUserO: User&Mock0bjecti...h8 usagesprivate function makesavedsearch(array sf1lters): SearchxMockobjectpubLic tunction tescbecAculvityLasrorsavedsearchkecurnstas: voldtpublic function testGetActivityIdsForSavedSearchReturnsEmptvWhenNoRdpublic function testGetActivityldsFilters0utDateFiltersO: void...public function testGetActivityldsFilters0utClosingPeriodDateFilter:public function testGetActiv1tyldsHandLesArrayF1lters: vo1di..pubLic tunction tescbecAculvltylashandlesscalarrilters: voldt..pubtao runctaontestGetActivitvIdsPassesNonZeroSequenceNumberToDisarpuser - ochis->makeusert,SsavedSearch = sthis->makeSavedSearch(u.D:sfilterset = Sthis->createMock originalClassName: FilterDefinitioncsthis->activitysearch->method constraint: 'getArrayr1lterKeys')->wScapturedcriteria = null;ninnS->acu vVsearch-sexdecsim s-sonce ui→>iecno constragetOnDemandPageFilterSet')1 eall-›il ~ Accept File *+ k (X Reject file (Griterta 2orätilesia) use ($fil, 0labl: Support Daily • in 2 h 54 m100% |45]Tue 14 Apr 12:06:06RequestGenerateAskJiminnyReportJobTestCascadeFixing ReportControlleAutomated Report Ma XFixing Ask Jiminny F+D ..ha RNow l have the key insight. Let me check what sequence_number does in the context of isFirstRequest() :searched ishlch wonp/Inis is tne root cause. Let me check AcCIVItyActualDace In delallNow I see the full picture. Let me also check ActivityDurationRange and ActivityRecorded defaults for isFirstRequestNow lhave the comnlete root cause nicture. iTihis is criticaikoor cause rounolThe bui ldRequestParamsFromSearch method in AskJiminnyReportActivityservice passes sequence_number=0implcitiy not in params, which means 1srir stkequest rerums true .When sequence_number Is notin requestparams, the criteria:: createrromkequest deraultsitto o, and isFirstRequesel letums true when elply seguencenunber ==0Ine trontend UkL has sequence number=4 — meaning il's not a tirst request. Ine service doesh't set it, so thecriteria thinks it's a first redlest.wnen isrirstkequestl) = true, these Impllcht tllters are apolled that aren tin tne savee seareh:1. ActivityDurationRange— applies min duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) - filters torecorded-only3. OrganiserGroupIn - applies user's default group filterBut the trontend with sequence number=4 skios alll of these deraults, so It returns more resultsThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence number in the built params tosignal "not a tirst recuest", so tne implicit derauls con t apoly. or alternatively, always pass a non-zero sequence number in the merge in getActivityldsForSavedSearch.Road Ack.liminnvRenortActivitService nhn " 44.02Now let me verty my understanalne or isrirstkequest.Read Criteria.nhoContirmed. The fix is clear and minimal. The getActivityldsForSavedSearch method needs to pass sequence_number with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.• AskJiminnvReportActivitvService.phpNow let me check t there's an existine lesttor AskJ1minnykeportaccivicyservice lo updaleI need to add a test that verifies sequence number=1 is passed to Criteria (so isFirstRequest() returns false).Letme ade Iulo tne existine lesttlle.• AskJiminnyReportActivityServiceTest.phpNowers run the esto vertv.• aоскer еxесcovel dgedocker lamp 1onp varwwwncnl arulsan cesttests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php ==no-Could not open input file: /var/www/html/artisan2 files +28-1%Reject allAccent alllAsk anything (&+L)+ ‹› CodeClaude Sonnet 4.6winasun leamsuir-oia 4 spacesw...
|
NULL
|
8134419933017474641
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodelaraveRetactonTool PhpStormFileFditViewNavigateCodelaraveRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.phpJiminnybeouecommana.ongAutomatedReportsCommand.php= custom.lo9= laravel.logL SF (iminny@localhostD UnitActionsComponentConfigurationM ConsoleM ContractsM7 DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTest→I Listeners→]Mal> MModelsM Notifications› M ObserversPoliciesProvidersRepositories> D Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedRenonAulomaleakeporissendcommand.ongC AddLayoutEntities.phpC Team.phpC) AutomatedReportsRepository.php XHs local liminnyalocalnostconsole PRODL console [EUl© AutomatedReportsService.php© CreateHeldActivityEvent.phpe) TrackProviderinstallled-vent.ono¿ consoe STAGING© AskJiminnyReportActivityService.phpC ActivityLogged.php© AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.phpC RequestGenerateAskJiminnyReportJob.phpC RequestGenerateReportJob.phpsrong© AutomatedReportResult.php© AutomatedReport.phpdeclare(strict_types=1);class AutomatedReportsrepos1toryA15 V4namesnace liests Unit Services Klosk AutomatedRenorts:* dreturn AutomatedReportuse...public function create(array $data): AutomatedReport...class AskaminnyReportActivityServicelest extends TestCase* Find an automated report by UUID*dparam string suuld25* drecurn Aurondredkeoorcnuupublic function findByUuid(string Suuid): ?AutomatedReportreturn AutomatedReport::where('uuid', AutomatedReport:: to0ptimized(Suuid))->firstO:2729 GT>Tusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReportif (is numeric(sidorluid)) "return AutomatedReport::where('uvid', AutomatedReport::to0ptimized(Sid0rUuid))->firstO;* Retrieve all standard (non-Ask Jiminny) automated reports.100 M ›* dparam string ssortcolumnThe column to sort by. Allowed values: 'created_by', 'created_at'. 118 %% >* @param string $sortDirection The sort direction. Allowed values:"asc, "desc". veraults to "des-oe157 % >* drerurn couuectonsaurondredredor*/12 usagespublic function getAllStandardReportsstring SsortColumn ="created at',string SsortDirection = 'desc': Collection 1...185 VA N206 D >-2242251*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam usersuserIne user wnose reporus to retrieve.*oparan scring esortho lunnThe column to sort by. Allowed values: 'created_by', 'created_at'. 232* Oparam string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'dez 233* dreturn Collection<AutomatedReport>22923023123425525614 usagesWinasun ch00 2.12.21: A new version is avallable. View chancelod loday 10:33.ls usadeslo usaces1o usages9 usagesprivate ActivitySearch&Mock0bject $activitySearch;private ElasticActivityRepository&Mock0bject SelasticRepository:private LoggerinterfacexMock0bject sloggerprivate AskJ1minnykeporcAculVityservice sservice;protected function setUp: voidt...hIl usagesprivate function makeFilter(string $key. ?string $value): SearchFilto usaeesprivate function makeUserO: User&Mock0bjecti...h8 usagesprivate function makesavedsearch(array sf1lters): SearchxMockobjectpubLic tunction tescbecAculvityLasrorsavedsearchkecurnstas: voldtpublic function testGetActivityIdsForSavedSearchReturnsEmptvWhenNoRdpublic function testGetActivityldsFilters0utDateFiltersO: void...public function testGetActivityldsFilters0utClosingPeriodDateFilter:public function testGetActiv1tyldsHandLesArrayF1lters: vo1di..pubLic tunction tescbecAculvltylashandlesscalarrilters: voldt..pubtao runctaontestGetActivitvIdsPassesNonZeroSequenceNumberToDisarpuser - ochis->makeusert,SsavedSearch = sthis->makeSavedSearch(u.D:sfilterset = Sthis->createMock originalClassName: FilterDefinitioncsthis->activitysearch->method constraint: 'getArrayr1lterKeys')->wScapturedcriteria = null;ninnS->acu vVsearch-sexdecsim s-sonce ui→>iecno constragetOnDemandPageFilterSet')1 eall-›il ~ Accept File *+ k (X Reject file (Griterta 2orätilesia) use ($fil, 0labl: Support Daily • in 2 h 54 m100% |45]Tue 14 Apr 12:06:06RequestGenerateAskJiminnyReportJobTestCascadeFixing ReportControlleAutomated Report Ma XFixing Ask Jiminny F+D ..ha RNow l have the key insight. Let me check what sequence_number does in the context of isFirstRequest() :searched ishlch wonp/Inis is tne root cause. Let me check AcCIVItyActualDace In delallNow I see the full picture. Let me also check ActivityDurationRange and ActivityRecorded defaults for isFirstRequestNow lhave the comnlete root cause nicture. iTihis is criticaikoor cause rounolThe bui ldRequestParamsFromSearch method in AskJiminnyReportActivityservice passes sequence_number=0implcitiy not in params, which means 1srir stkequest rerums true .When sequence_number Is notin requestparams, the criteria:: createrromkequest deraultsitto o, and isFirstRequesel letums true when elply seguencenunber ==0Ine trontend UkL has sequence number=4 — meaning il's not a tirst request. Ine service doesh't set it, so thecriteria thinks it's a first redlest.wnen isrirstkequestl) = true, these Impllcht tllters are apolled that aren tin tne savee seareh:1. ActivityDurationRange— applies min duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) - filters torecorded-only3. OrganiserGroupIn - applies user's default group filterBut the trontend with sequence number=4 skios alll of these deraults, so It returns more resultsThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence number in the built params tosignal "not a tirst recuest", so tne implicit derauls con t apoly. or alternatively, always pass a non-zero sequence number in the merge in getActivityldsForSavedSearch.Road Ack.liminnvRenortActivitService nhn " 44.02Now let me verty my understanalne or isrirstkequest.Read Criteria.nhoContirmed. The fix is clear and minimal. The getActivityldsForSavedSearch method needs to pass sequence_number with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.• AskJiminnvReportActivitvService.phpNow let me check t there's an existine lesttor AskJ1minnykeportaccivicyservice lo updaleI need to add a test that verifies sequence number=1 is passed to Criteria (so isFirstRequest() returns false).Letme ade Iulo tne existine lesttlle.• AskJiminnyReportActivityServiceTest.phpNowers run the esto vertv.• aоскer еxесcovel dgedocker lamp 1onp varwwwncnl arulsan cesttests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php ==no-Could not open input file: /var/www/html/artisan2 files +28-1%Reject allAccent alllAsk anything (&+L)+ ‹› CodeClaude Sonnet 4.6winasun leamsuir-oia 4 spacesw...
|
10967
|
|
10970
|
217
|
40
|
2026-04-14T09:06:09.944850+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157569944_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityServiceTest.ph faVsco.js – AskJiminnyReportActivityServiceTest.php...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.76171875,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.7796875,"top":0.017361112,"width":0.12109375,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","depth":4,"bounds":{"left":0.490625,"top":0.12777779,"width":0.3347656,"height":0.8722222},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.4234375,"top":0.1736111,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.43710938,"top":0.1736111,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.4484375,"top":0.17222223,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.45703125,"top":0.17222223,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"bounds":{"left":0.15234375,"top":0.0,"width":0.39882812,"height":1.0},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8932460332387265586
|
-8276790037575160524
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $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...
|
NULL
|
|
10971
|
217
|
41
|
2026-04-14T09:06:16.010317+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157576010_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodelaraveRetactonTool PhpStormFileFditViewNavigateCodelaraveRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.phpJiminnybeouecommana.ongAutomatedReportsCommand.phpD Unit_ ActionsComponentConfigurationM ConsoleM ContractsM7 DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReportsAulomaleakeporissendcommand.ongC AddLayoutEntities.phpC Team.phpC) AutomatedReportsRepository.php X© AutomatedReportsService.php© CreateHeldActivityEvent.phpe) Track?rovidernstalled-vent.onoC ActivityLogged.phpC RequestGenerateAskJiminnyReportJob.phpRequestGeneratekeportJob.ong© AutomatedReportResult.php© AutomatedReport.phpclass AutomatedReportsrepos1tory©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTest→I Listeners→]Mal> MModelsM Notifications› M ObserversPoliciesProvidersRepositories> D Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c AutomatedRenorA15 V4 ^* dreturn AutomatedReportpublic function create(array $data): AutomatedReport...* Find an automated report by UUID*dparam string suuld* drecurn Aurondredkeoorcnuupublic function findByUuid(string Suuid): ?AutomatedReport118 M >return AutomatedReport::where('uuid', AutomatedReport:: to0ptimized(Suuid))->firstO:157 Y185 M >Tusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReport206 >if (is numeric(sidorluid)) "225 D226227return AutomatedReport::where('uvid', AutomatedReport::to0ptimized(Sid0rUuid))->firstO;* Retrieve all standard (non-Ask Jiminny) automated reports.250LOJ232- 233* dparam string ssortcolumnThe column to sort by. Allowed values: 'created_by", 'created_at'. 239* @param string $sortDirection The sort direction. Allowed values:"asc, "desc". veraults to "0ex236* drerurn couuectonsaurondredredor*/12 usagespublic function getAllStandardReportsstring SsortColumn ="created at',string SsortDirection = 'desc': Collection 1...*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam usersuserIne user wnose reporus to retrieve.242124512441245246247248249250_251252 0 >274*oparan scring esortho lunnIne cocumn co sorc oy. Accowed values. creaced_oy, creaced_ar". 275)* Oparam string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'dez* dreturn Collection<AutomatedReport>14 usagesWinasur ch00 2.12.21: A new version is avallable. View chancelod loday 10:33.= custom.lo9= laravel.logL SF (iminny@localhostHs local liminnyalocalnostconsole PRODL console (EUl¿ consoe STAGINGI© AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.phpclass AskuLminnyкeporcActIviLyservicelest extenas lescuase290>procecced tunccion secupl: voldt...s11 usagesprivate function makeFilter(string $key, ?string $value): SearchFil1o usagesprivate function makeUserO: User&MockObject...8 usagesprivate function makesavedsearch(array sfilters): SearchxMock0bjectpublic function testGetActivityldsForsavedsearchReturnsuds(): vo1dtpubLic tunction tescbecAculvityLasrorsavedsearchkecurnsemptywnennokououc Tuncmion testcerAcewrosruersuurvatertuerstur voglonrapublic function testGetActivityldsFilters0utClosingPeriodDateFiltenpublic function testGetActivityldsHandlesArrayFiltersO: void.public function testGetActiv1tyldsHandlesscalarr1lters: vo1di...fo ae runecion, testoelactava y easressesnonderoseavencen men louasaesuser = schis->makeuseru;SsavedSearch = Sthis->nakeSavedSearchdiD:$filterSet = Sthis->createMock( originalClassName: FilterDefinitionCsthis->activitySearch->method( constraint:getArrayFilterKeys )->nscapturedcriteria = nului$this->activitySearch->expects ($this->onceO)getonDemandPagerilterset")->willReturnCallback(function (Criteria $criteria) use ($fiSthis-›elasticRepository->methodd constraint: "onDemandSearchIdsOnlSthis->loggen->methodc constraint: "info'):sthis-›service->getActivityldsForSavedSearch($savedSearch. suse.sthis->assertNotNull(ScapturedCriteria):sthis->assertralse(scapturedCriter1a->1sF1rstRequestOJhpubLic tunction tescbecAculvitylasLogswichcorrectconcextl: voldt..1 eailAcceot rlle do+X Reject File 4 %@+ 2 of 2 files →, 0labl: Support Daily • in 2 h 54 m100% |45]Tue 14 Apr 12:06:15RequestGenerateAskJiminnyReportJobTestCascadeFixing ReportControlleAutomated Report Ma© Fixing Ask Jiminny F+D ..nd.php#L211 and add validation with logs inside@AutomatedReportsCommand. php#L209-213Let me read the current state of the command file first.kead Automareakeporscommand.ongIcan see the user's approach - processsing LeReport already exists trom my earlier work but getReportByld iswhat's being used in processReports.Ineed to implement getReportById properly with validation + logs, and addthe reposilory method. Let me also check the Illuminate Support collection impon situation:Searched use Illuminate (Support Collection in app/Console/Commands/Reports/AutomatedReportsCommand.ph.Now implement both changes - the repository method and the getReportByld method with proper validation:trror while editing automacedkeportscommand. pnpPoad AutomatedReoorscommana.ong /The file is now only 140 lines - the user removed the processSingleReport/warnIfNotApplicableForSchedulemetnoas. Now "l implement oot changes:AutomatedReportsCommand.php+57 -1Now add findByldorUuid to the repository:• AutomatedReportsRepository.phpAlso fix the import order Collection should be before the models alphabetically):• AutomatedReportsCommand.php+1 -1• AutomatedReportsCommand.php+1-1Done. summary or changes:AutomatedReportsRepository::findByld0rUuid() (AutomatedReportsRepository-php:47-54):• Numeric string → find() by int ID• Non-numeric → UUID lookup via toOptimized()• Both use withTrashed() so soft-deleted reports are findable manuallygetReportById() (AutomatedReportsCommand.php:135-194) - checks all conditions that getActiveReportsByFrequency entorces, loceine a warnine to the loe channel ane orintne a warn lo the terminal tor eaeh violation,out stlll returns the revort so orocessina continuesCheckBehaviour on failNot toundwarnino loo + terminal warn. returns emory collection skios processino))nactive statuswarning log + terminal warn, continuesTeam not activewarnind llod + terminal warn. continuesExoiredwarning log + terminal warn, continuesrrecuency woulentrun toodyinfo log + terminal warn, continueswGAl mAsk anything (&+L)+ < CodeClaude Sennet 4.6winasun leamsuir-oia 4 spaces...
|
NULL
|
525892152718833132
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodelaraveRetactonTool PhpStormFileFditViewNavigateCodelaraveRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.phpJiminnybeouecommana.ongAutomatedReportsCommand.phpD Unit_ ActionsComponentConfigurationM ConsoleM ContractsM7 DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReportsAulomaleakeporissendcommand.ongC AddLayoutEntities.phpC Team.phpC) AutomatedReportsRepository.php X© AutomatedReportsService.php© CreateHeldActivityEvent.phpe) Track?rovidernstalled-vent.onoC ActivityLogged.phpC RequestGenerateAskJiminnyReportJob.phpRequestGeneratekeportJob.ong© AutomatedReportResult.php© AutomatedReport.phpclass AutomatedReportsrepos1tory©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTest→I Listeners→]Mal> MModelsM Notifications› M ObserversPoliciesProvidersRepositories> D Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c AutomatedRenorA15 V4 ^* dreturn AutomatedReportpublic function create(array $data): AutomatedReport...* Find an automated report by UUID*dparam string suuld* drecurn Aurondredkeoorcnuupublic function findByUuid(string Suuid): ?AutomatedReport118 M >return AutomatedReport::where('uuid', AutomatedReport:: to0ptimized(Suuid))->firstO:157 Y185 M >Tusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReport206 >if (is numeric(sidorluid)) "225 D226227return AutomatedReport::where('uvid', AutomatedReport::to0ptimized(Sid0rUuid))->firstO;* Retrieve all standard (non-Ask Jiminny) automated reports.250LOJ232- 233* dparam string ssortcolumnThe column to sort by. Allowed values: 'created_by", 'created_at'. 239* @param string $sortDirection The sort direction. Allowed values:"asc, "desc". veraults to "0ex236* drerurn couuectonsaurondredredor*/12 usagespublic function getAllStandardReportsstring SsortColumn ="created at',string SsortDirection = 'desc': Collection 1...*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam usersuserIne user wnose reporus to retrieve.242124512441245246247248249250_251252 0 >274*oparan scring esortho lunnIne cocumn co sorc oy. Accowed values. creaced_oy, creaced_ar". 275)* Oparam string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'dez* dreturn Collection<AutomatedReport>14 usagesWinasur ch00 2.12.21: A new version is avallable. View chancelod loday 10:33.= custom.lo9= laravel.logL SF (iminny@localhostHs local liminnyalocalnostconsole PRODL console (EUl¿ consoe STAGINGI© AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.phpclass AskuLminnyкeporcActIviLyservicelest extenas lescuase290>procecced tunccion secupl: voldt...s11 usagesprivate function makeFilter(string $key, ?string $value): SearchFil1o usagesprivate function makeUserO: User&MockObject...8 usagesprivate function makesavedsearch(array sfilters): SearchxMock0bjectpublic function testGetActivityldsForsavedsearchReturnsuds(): vo1dtpubLic tunction tescbecAculvityLasrorsavedsearchkecurnsemptywnennokououc Tuncmion testcerAcewrosruersuurvatertuerstur voglonrapublic function testGetActivityldsFilters0utClosingPeriodDateFiltenpublic function testGetActivityldsHandlesArrayFiltersO: void.public function testGetActiv1tyldsHandlesscalarr1lters: vo1di...fo ae runecion, testoelactava y easressesnonderoseavencen men louasaesuser = schis->makeuseru;SsavedSearch = Sthis->nakeSavedSearchdiD:$filterSet = Sthis->createMock( originalClassName: FilterDefinitionCsthis->activitySearch->method( constraint:getArrayFilterKeys )->nscapturedcriteria = nului$this->activitySearch->expects ($this->onceO)getonDemandPagerilterset")->willReturnCallback(function (Criteria $criteria) use ($fiSthis-›elasticRepository->methodd constraint: "onDemandSearchIdsOnlSthis->loggen->methodc constraint: "info'):sthis-›service->getActivityldsForSavedSearch($savedSearch. suse.sthis->assertNotNull(ScapturedCriteria):sthis->assertralse(scapturedCriter1a->1sF1rstRequestOJhpubLic tunction tescbecAculvitylasLogswichcorrectconcextl: voldt..1 eailAcceot rlle do+X Reject File 4 %@+ 2 of 2 files →, 0labl: Support Daily • in 2 h 54 m100% |45]Tue 14 Apr 12:06:15RequestGenerateAskJiminnyReportJobTestCascadeFixing ReportControlleAutomated Report Ma© Fixing Ask Jiminny F+D ..nd.php#L211 and add validation with logs inside@AutomatedReportsCommand. php#L209-213Let me read the current state of the command file first.kead Automareakeporscommand.ongIcan see the user's approach - processsing LeReport already exists trom my earlier work but getReportByld iswhat's being used in processReports.Ineed to implement getReportById properly with validation + logs, and addthe reposilory method. Let me also check the Illuminate Support collection impon situation:Searched use Illuminate (Support Collection in app/Console/Commands/Reports/AutomatedReportsCommand.ph.Now implement both changes - the repository method and the getReportByld method with proper validation:trror while editing automacedkeportscommand. pnpPoad AutomatedReoorscommana.ong /The file is now only 140 lines - the user removed the processSingleReport/warnIfNotApplicableForSchedulemetnoas. Now "l implement oot changes:AutomatedReportsCommand.php+57 -1Now add findByldorUuid to the repository:• AutomatedReportsRepository.phpAlso fix the import order Collection should be before the models alphabetically):• AutomatedReportsCommand.php+1 -1• AutomatedReportsCommand.php+1-1Done. summary or changes:AutomatedReportsRepository::findByld0rUuid() (AutomatedReportsRepository-php:47-54):• Numeric string → find() by int ID• Non-numeric → UUID lookup via toOptimized()• Both use withTrashed() so soft-deleted reports are findable manuallygetReportById() (AutomatedReportsCommand.php:135-194) - checks all conditions that getActiveReportsByFrequency entorces, loceine a warnine to the loe channel ane orintne a warn lo the terminal tor eaeh violation,out stlll returns the revort so orocessina continuesCheckBehaviour on failNot toundwarnino loo + terminal warn. returns emory collection skios processino))nactive statuswarning log + terminal warn, continuesTeam not activewarnind llod + terminal warn. continuesExoiredwarning log + terminal warn, continuesrrecuency woulentrun toodyinfo log + terminal warn, continueswGAl mAsk anything (&+L)+ < CodeClaude Sennet 4.6winasun leamsuir-oia 4 spaces...
|
10970
|
|
10974
|
217
|
43
|
2026-04-14T09:06:19.191460+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157579191_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodelaraveRetactonTool PhpStormFileFditViewNavigateCodelaraveRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.phpJiminnybeouecommana.ongAutomatedReportsCommand.phpD Unit_ ActionsComponentConfigurationM ConsoleM ContractsM7 DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReportsAulomaleakeporissendcommand.ongC AddLayoutEntities.phpC Team.phpC) AutomatedReportsRepository.php X© AutomatedReportsService.php© CreateHeldActivityEvent.phpe) Track?rovidernstalled-vent.onoC ActivityLogged.phpC RequestGenerateAskJiminnyReportJob.phpRequestGeneratekeportJob.ong© AutomatedReportResult.php© AutomatedReport.phpclass AutomatedReportsrepos1tory©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTest→I Listeners→]Mal> MModelsM Notifications› M ObserversPoliciesProvidersRepositories> D Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c AutomatedRenorA15 V4 ^* dreturn AutomatedReportpublic function create(array $data): AutomatedReport...* Find an automated report by UUID*dparam string suuld* drecurn Aurondredkeoorcnuupublic function findByUuid(string Suuid): ?AutomatedReport118 M >return AutomatedReport::where('uuid', AutomatedReport:: to0ptimized(Suuid))->firstO:157 Y185 MTusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReport206 >if (is numeric(sidorluid)) "225 D226227return AutomatedReport::where('uvid', AutomatedReport::to0ptimized(Sid0rUuid))->firstO;* Retrieve all standard (non-Ask Jiminny) automated reports.250LOJ232- 233* dparam string ssortcolumnThe column to sort by. Allowed values: 'created_by', 'created_at'. 235* @param string $sortDirection The sort direction. Allowed values:"asc, "desc". veraults to "0ex236* drerurn couuectonsaurondredredor*/12 usagespublic function getAllStandardReportsstring SsortColumn ="created at',string SsortDirection = 'desc': Collection 1...*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam usersuserIne user wnose reporus to retrieve.2421243144245240247248249250_251252 0 >274*oparan scring esortho lunnIne cocumn co sorc oy. Accowed vacues. created_oy, "creaced_ac". 275)* Oparam string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'dez* dreturn Collection<AutomatedReport>14 usagesWinasun ch00 2.12.21: A new version is avallable." View Chancelod loday 10:33.= custom.lo9= laravel.logL SF (iminny@localhostHs local liminnyalocalnostconsole PRODL console [EUl& consoe STAGING© AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.phpclass AskuLminnyкeporcActIviLyservicelest extenas lesclase29@>procecced tunccion secupl: voldt...s11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilto usagesprivate function makeUserO: User&MockObject...8 usagesprivate function makesavedsearch(array sfilters): SearchxMock0bjectpublic function testGetActivityldsrorSavedSearchReturnsids(: vo1dpubLic tunction tescbecAculvityLasrorsavedsearchkecurnsemptywnennokpublic function testGetActivitvIdsFiltersOutDateFilters@: void...public function testGetActivityldsFilters0utClosingPeriodDateFiltenpublic function testGetActivityldsHandlesArrayFiltersO: void..public function testGetActiv1tyldsHandlesscalarr1lters: vo1di...fo ae runecion, testoelactava y easressesnonderoseavencen men louasaesuser = schis->makeuseru;SsavedSearch = Sthis->makeSavedSearchdiD:$filterSet = Sthis->createMock( originalClassName: FilterDefinitionCsthis->activitySearch->method( constraint:getArrayFilterKeys )->uscapturedcriteria = nului$this->activitySearch->expects ($this->onceO)iDemandPageF1lterset')->willReturnCallback(function (Criteria $criteria) use ($filSthis-›elasticRepository->methodd constraint: "onDemandSearchIdsOnlSthis->logger->method constraint: "info'):sthis-›service->getActivityldsForSavedSearch($savedSearch. suse.sthis->assertNotNull(ScapturedCriteria)isthis->assertralse(scapturedCr1ter1a->1sF1rstRequest0J:pubLic tunction testbetactivity-asLogswchcorrectcontexto: volar.1 eailAcceot rlle do+X Reject File 4 %@+ 2 of 2 files →, 0lablSupport Daily • in 2 h 54m100% |45]Tue 14 Apr 12:06:18RequestGenerateAsk.liminnvRenort.lob TestCascadeFixing ReportControlleAutomated Report Ma© Fixing Ask Jiminny F+0 .Now nave tne root cause. Letme look al sequence nunber Tier soecitically.searcneo seduence numoer secuencenumoer ano venormeo z other ouerles»Now l have the key insight. Let me check what sequence_number does in the context of isFirstRequest() :Inis is tne root cause. Let me check AcClvityActualDace in celall.Now I see the full picture. Let me also check ActivityDurationRange and ActivityRecorded detaults for isFirstRequestRead ActivityDurationRange.php and ActivityRecorded.phpNow |have the comolete root cause picture. This is critica.koor cause rounoThe bur dRequestPanarch method in AskJiminnyReportActivityService passes sequence_number=0implcitiy not in params, whieh means 1srir Stkequest rerums true.When sequence_number Is notin requestparams, the criteria:: createrromkequest deraultsitto o, and isrirstRequest() returns true when empty |l sequenceNumber == 0.Ine trontend UkL has sequence number=4 — meaning il's not a tirst reouest. Ine service doesh't ser it, so thecriteria thinks it's a first request.When isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange — applies min duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) - filters torecorded-only3. OrganiserGroupIn - applies user's default group filterBut the trontend with sequence_number=4 skips all of these defaults, so it returns more results.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence number in the built params tosignal "not a tirst recuest" so the implicit derauls con t apoly. or alternatively, always pass a non-zero sequence number in the merge in getActivityldsForSavedSearch.Now let me verify my understanding of isFirstRequest :Read Criteria.phpContirmed. The fix is clear and minimal. The getActivityldsForSavedSearch method needs to pass sequence_number with a non-zero value so tnat 1srirstkequestl returns Talse ane no impllclt deraults are appllea.• Ask.JNow let me check iT there's an existine lestror AskJ1minnykeportaccivicyservice lo uodare:ExploredAskJiminnvReoortActivtvServicelest.onv and searched.Ask.iminnvReoortActivitvI need to add a test that verifies sequence number=1 is passed to Criteria (so isFirstRequest() hiturns false).Letme ade lulo tne existine lesttlle.• AskJ.Now let's run the test to veriry:aocker execinnyReportActivityServiceTest.php --no-Could not open input file: /var/www/html/artisanCommand dockeno dests/nxe/sdrvkces/K105k/Automate/aeports/A5kJiminnyReportActivityserviceTest.php -no-2 files +28-1%Reject allAccent allAsk anything (&+L)+ & CodeClaude Sonnet 4.6winasun leamsuir-oia 4 spaces...
|
NULL
|
-6347880079697164300
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodelaraveRetactonTool PhpStormFileFditViewNavigateCodelaraveRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.phpJiminnybeouecommana.ongAutomatedReportsCommand.phpD Unit_ ActionsComponentConfigurationM ConsoleM ContractsM7 DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReportsAulomaleakeporissendcommand.ongC AddLayoutEntities.phpC Team.phpC) AutomatedReportsRepository.php X© AutomatedReportsService.php© CreateHeldActivityEvent.phpe) Track?rovidernstalled-vent.onoC ActivityLogged.phpC RequestGenerateAskJiminnyReportJob.phpRequestGeneratekeportJob.ong© AutomatedReportResult.php© AutomatedReport.phpclass AutomatedReportsrepos1tory©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTest→I Listeners→]Mal> MModelsM Notifications› M ObserversPoliciesProvidersRepositories> D Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c AutomatedRenorA15 V4 ^* dreturn AutomatedReportpublic function create(array $data): AutomatedReport...* Find an automated report by UUID*dparam string suuld* drecurn Aurondredkeoorcnuupublic function findByUuid(string Suuid): ?AutomatedReport118 M >return AutomatedReport::where('uuid', AutomatedReport:: to0ptimized(Suuid))->firstO:157 Y185 MTusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReport206 >if (is numeric(sidorluid)) "225 D226227return AutomatedReport::where('uvid', AutomatedReport::to0ptimized(Sid0rUuid))->firstO;* Retrieve all standard (non-Ask Jiminny) automated reports.250LOJ232- 233* dparam string ssortcolumnThe column to sort by. Allowed values: 'created_by', 'created_at'. 235* @param string $sortDirection The sort direction. Allowed values:"asc, "desc". veraults to "0ex236* drerurn couuectonsaurondredredor*/12 usagespublic function getAllStandardReportsstring SsortColumn ="created at',string SsortDirection = 'desc': Collection 1...*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam usersuserIne user wnose reporus to retrieve.2421243144245240247248249250_251252 0 >274*oparan scring esortho lunnIne cocumn co sorc oy. Accowed vacues. created_oy, "creaced_ac". 275)* Oparam string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'dez* dreturn Collection<AutomatedReport>14 usagesWinasun ch00 2.12.21: A new version is avallable." View Chancelod loday 10:33.= custom.lo9= laravel.logL SF (iminny@localhostHs local liminnyalocalnostconsole PRODL console [EUl& consoe STAGING© AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.phpclass AskuLminnyкeporcActIviLyservicelest extenas lesclase29@>procecced tunccion secupl: voldt...s11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilto usagesprivate function makeUserO: User&MockObject...8 usagesprivate function makesavedsearch(array sfilters): SearchxMock0bjectpublic function testGetActivityldsrorSavedSearchReturnsids(: vo1dpubLic tunction tescbecAculvityLasrorsavedsearchkecurnsemptywnennokpublic function testGetActivitvIdsFiltersOutDateFilters@: void...public function testGetActivityldsFilters0utClosingPeriodDateFiltenpublic function testGetActivityldsHandlesArrayFiltersO: void..public function testGetActiv1tyldsHandlesscalarr1lters: vo1di...fo ae runecion, testoelactava y easressesnonderoseavencen men louasaesuser = schis->makeuseru;SsavedSearch = Sthis->makeSavedSearchdiD:$filterSet = Sthis->createMock( originalClassName: FilterDefinitionCsthis->activitySearch->method( constraint:getArrayFilterKeys )->uscapturedcriteria = nului$this->activitySearch->expects ($this->onceO)iDemandPageF1lterset')->willReturnCallback(function (Criteria $criteria) use ($filSthis-›elasticRepository->methodd constraint: "onDemandSearchIdsOnlSthis->logger->method constraint: "info'):sthis-›service->getActivityldsForSavedSearch($savedSearch. suse.sthis->assertNotNull(ScapturedCriteria)isthis->assertralse(scapturedCr1ter1a->1sF1rstRequest0J:pubLic tunction testbetactivity-asLogswchcorrectcontexto: volar.1 eailAcceot rlle do+X Reject File 4 %@+ 2 of 2 files →, 0lablSupport Daily • in 2 h 54m100% |45]Tue 14 Apr 12:06:18RequestGenerateAsk.liminnvRenort.lob TestCascadeFixing ReportControlleAutomated Report Ma© Fixing Ask Jiminny F+0 .Now nave tne root cause. Letme look al sequence nunber Tier soecitically.searcneo seduence numoer secuencenumoer ano venormeo z other ouerles»Now l have the key insight. Let me check what sequence_number does in the context of isFirstRequest() :Inis is tne root cause. Let me check AcClvityActualDace in celall.Now I see the full picture. Let me also check ActivityDurationRange and ActivityRecorded detaults for isFirstRequestRead ActivityDurationRange.php and ActivityRecorded.phpNow |have the comolete root cause picture. This is critica.koor cause rounoThe bur dRequestPanarch method in AskJiminnyReportActivityService passes sequence_number=0implcitiy not in params, whieh means 1srir Stkequest rerums true.When sequence_number Is notin requestparams, the criteria:: createrromkequest deraultsitto o, and isrirstRequest() returns true when empty |l sequenceNumber == 0.Ine trontend UkL has sequence number=4 — meaning il's not a tirst reouest. Ine service doesh't ser it, so thecriteria thinks it's a first request.When isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange — applies min duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) - filters torecorded-only3. OrganiserGroupIn - applies user's default group filterBut the trontend with sequence_number=4 skips all of these defaults, so it returns more results.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence number in the built params tosignal "not a tirst recuest" so the implicit derauls con t apoly. or alternatively, always pass a non-zero sequence number in the merge in getActivityldsForSavedSearch.Now let me verify my understanding of isFirstRequest :Read Criteria.phpContirmed. The fix is clear and minimal. The getActivityldsForSavedSearch method needs to pass sequence_number with a non-zero value so tnat 1srirstkequestl returns Talse ane no impllclt deraults are appllea.• Ask.JNow let me check iT there's an existine lestror AskJ1minnykeportaccivicyservice lo uodare:ExploredAskJiminnvReoortActivtvServicelest.onv and searched.Ask.iminnvReoortActivitvI need to add a test that verifies sequence number=1 is passed to Criteria (so isFirstRequest() hiturns false).Letme ade lulo tne existine lesttlle.• AskJ.Now let's run the test to veriry:aocker execinnyReportActivityServiceTest.php --no-Could not open input file: /var/www/html/artisanCommand dockeno dests/nxe/sdrvkces/K105k/Automate/aeports/A5kJiminnyReportActivityserviceTest.php -no-2 files +28-1%Reject allAccent allAsk anything (&+L)+ & CodeClaude Sonnet 4.6winasun leamsuir-oia 4 spaces...
|
10973
|
|
10979
|
217
|
46
|
2026-04-14T09:06:25.541392+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157585541_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactonToo PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vv _ AutomatedReports(C) ActivityTypeService.(C AskJiminnyReportAc(C) AutomatedReportse(C) AutomatedReportsS© DealStagesService.p© Recipientsservice.pr@ Reportsort.php(e) Reporisonbirection.Kloskservice.php> M Mail_ MeetingGenerator> NotificationD 0Auth2RecallAl_ Security_ StrategyStreamingM TeamTelephonyM UserPilotM Webhook© AbstractService.php© ActivityProviderFactory.phC) ActivityService.phpC ApiResponseService.php(C) ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© Intercomservice.php© IpapiClient.phpC) IpapiService.phpC) ParticioantShareService.phC PlanhatService.ohp(C) PlaybackService.php(C PlaybackVideoOnlyService(C) PlaybookCategoryService.lC PlaylistGeneratorinterface.(C) ResolveTeamCrmConnectiC SimpleThrottleService.php© slackservice.php© SocialAccountService.php© SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php(C) TeamService.phpC) TranscodeParameterResolC UserService.phpC) Uuid.php› C Traits• → UseCases> D UserDUtils• I validation•IV0pnp nelpers.png(C InitialFrontendState.php(©) Jiminny.php(C) Plan.php(©) ReportController.phpJiminnybeouecommana.ongAutomatedReportsCommand.php© AutomatedReportsSendCommand.phpC AddLayoutEntities.phpC) Team.phpC) AutomatedReportsRepository.php X) AutomatedReportsService.php© CreateHeldActivityEvent.phpe) Track?roviderinstalled-vent.onoC ActivityLogged.phpC RequestGenerateAskJiminnyReportJob.phpRequestGeneratekeportJob.ong© AutomatedReportResult.php© AutomatedReport.phpclass AutomatedReportsrepos1tory62A15 V4 ^-14* dreturn AutomatedReportpublic function create(array $data): AutomatedReport...* Find an automated report by UUID*dparam string suuld* drecurn Aurondredkeoorcnuupublic function findByUuid(string Suuid): ?AutomatedReportreturn AutomatedReport::where('uuid', AutomatedReport:: to0ptimized(Suuid))->firstO:Tusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReportif (is numeric(sidorluid)) "return Automacedkeport..tznal(1nt) s1auruu1a);return AutomatedReport::where('uvid', AutomatedReport::to0ptimized(Sid0rUuid))->firstO;* Retrieve all standard (non-Ask Jiminny) automated reports.* dparam string ssortcolumnThe column to sort by. Allowed values: 'created_by", 'created_at'. 46* dparam string SsortDirection The sort direction. Allowed values:"asc","desc". befaults to "des47* drerurn couuectonsaurondredredor*/12 usagespublic function getAllStandardReportsstring SsortColumn ="created_at',string SsortDirection = 'desc': Collection 1...*** Recrieve aLL Ask Jaminny reporus created Dy the given user.—57* dparam usersuserIne user wnose reporus to retrieve.*oparan scring esortho lunnIne cocumn co sorc by. Accowed vacues. createa_by!creaced_ar".xoocran saino osorcutreccion lne sorc anreccion. Accoyeo vocues.'asc'.'desc'. Defaults to 'dex 6e* dreturn Collection<AutomatedReport>14 usagesWinasurt changelog 2.12.21: A new version is avallable. |/ View Changelog (today 10:33)= custom.log= laravel.logL SF (iminny@localhostHs local liminnyalocalnostconsole PRODL console [EUl¿ consoe STAGINGI© AskJiminnyReportActivityService.php x©) AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpuseJlninny Models Acclvity seareh,useJiminny Models User:use Jiminny Repositories ElasticActivityRepository:use Jiminny VO Repository OnDemandActivitySearch\Criteria;use Psr\Log Loggerinterface;class ASKJ1minnyReportAct1vityserviceonvare const nt UEFAULI UP ACILEES CUUN = 100private const arrav DATE FILTER KEYS =AccIvLcyAccuaLbace..PARAM_SIAKI_UAlE.ActivityActualDate:: PARAM END DATE.ActivityUpdatedDate::PARAM_UPDATED_FROMActivityUpdatedDate::PARAM_UPDATED_TO.ClosingPer1odF1lter::KEY_START_DATE,ClosingPer1odF1lter::KEY_END_DATE,pubuic tunction __conscructlprivace readonly Aculviltysearch saccivitysearch,privace readonty clascicactiviсукeposicory selasucкepository.private readonty Loggerincertace +logger,Df...r*** Fetch activity IDs for a saved search, passing 1ts filters as-1s* Date filters stored on the saved search are excluded; 1f no othen* no date constraint 1s applied - matching the behaviour of getcont.* Oreturn string[] Activity IDspublic function getActivitvIdsForSavedSearchdSearch SsavedSearch.User suser,D: arraySrequestParams = Sthis->buildRequestParamsFromSearchSsavedSearc.scriteria = criteria::createrromrequestlAcceptmarьa-SrequestParams. "'Timit' => self::DEFAULT TOP AC1array_mergelsrequestrarams, L'Limlu => seLt::UEFAULI_10P_ACnuser-poernezone$filterSet = Sthis-›activitySearch->qetOnDemandPageFilterSet(ScriSactivityIds = sthis->elasticRepository->onDemandSearchlds0nly(Ssth1s->Logger->1nfolLAskJ1minnyReport) Fetched activity IDs fon=> ssavedSearch->getid)."user_1d = suser->gecia).=> count(SactivitvIds).1):Accept rlle ao+X Reject File 40 38 @* 1 of 2 files →, 0lablSupport Daily • in 2 h 54m100% |45]Tue 14 Apr 12:06:25RequestGenerateAsk.liminnvRenort.lob TestCascadeFixing ReportControlleAutomated Report Ma© Fixing Ask Jiminny FNow see tne Tul o clure, Lerme also check Activitvlurat ionkande ano Actwvitvkecorded ceauis or 1sFirstRequeseureReao Acuviyburauonkance ono ano Acrivivrecorcec.onoNow Inave tne comolere roo, cause o cture. nis s crucarKoot cause rounene oua lokequestraramsrromsearch mernocin Ask aminnvredortActvl vservice vasses sequence number=implicitly (not in params), which means isFirstRequest() returns true.When sequence number Is notin requestParams, the criteria:: createrromkequest delaulsitlo o, and 1sr1rstRequest() returns true when empty sequenceNumber == 0The frontend URL has sequence number=4 - meaning it's not a first request. The service doesn't set it, so thecriera thinks iu's atrstrecuestWhen isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. Activityburationkange — applies min_duration = 1 (INITIAL_MIN) - Tllters out U-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) - filters torecorded-ohly3. OrganiserGroupln - applies user's detault group filterbut the Trontend With sequence number=4 sklos all or these derauls, so it returns more resuits.The fix should be in bui ldRequestParamsFromsearch - it needs to pass sequence_number in the built params tosignal "not a first request", so the implicit defaults don't apply. Or alternatively, always pass a non-zero sequence number In tne merce in derAcuivlivlostorsaveNow let me verify my understanding of isFirstRequest :reao criera,onoConirmeo, Ine rixis cear ano minimar Une oetActivlvlosrorsavedsearch menoo neeos o oass sequence nurber with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.• Ask.Now let me check if there's an existing test for AskJiminnyReportActivityService to update:Explored AskJiminnyReportActivityServiceTest.php and searched AskJiminnyReportActivity*need to add a test that verifies sequence number=1 IS passed to Criteria (so 1sFirstRequest( returns false )Let me add it to the existing test file:• AskJ.LACIVILyoervicelestongNow ler's tun tne lestto verity.aосker Lamplpnp /var/www/ncml/drc1san lesytests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServicelest.php -=no-covelayeCould not open input file: /var/www/html/artisanCommand dockenO cocker exec vocker lano i ono aoparusan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php -=no-coverrageRun &+ Skip2 files with changestests/Unit/services/Klosk Automatedkenoris/AskJiminnvrenortActivivservicellest.onoView allapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (&+L)+ <> CodeClaude Sennet 4.6Wwinasur leamsuir-oia 4 spaces...
|
NULL
|
4427173165647033107
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactonToo PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vv _ AutomatedReports(C) ActivityTypeService.(C AskJiminnyReportAc(C) AutomatedReportse(C) AutomatedReportsS© DealStagesService.p© Recipientsservice.pr@ Reportsort.php(e) Reporisonbirection.Kloskservice.php> M Mail_ MeetingGenerator> NotificationD 0Auth2RecallAl_ Security_ StrategyStreamingM TeamTelephonyM UserPilotM Webhook© AbstractService.php© ActivityProviderFactory.phC) ActivityService.phpC ApiResponseService.php(C) ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© Intercomservice.php© IpapiClient.phpC) IpapiService.phpC) ParticioantShareService.phC PlanhatService.ohp(C) PlaybackService.php(C PlaybackVideoOnlyService(C) PlaybookCategoryService.lC PlaylistGeneratorinterface.(C) ResolveTeamCrmConnectiC SimpleThrottleService.php© slackservice.php© SocialAccountService.php© SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php(C) TeamService.phpC) TranscodeParameterResolC UserService.phpC) Uuid.php› C Traits• → UseCases> D UserDUtils• I validation•IV0pnp nelpers.png(C InitialFrontendState.php(©) Jiminny.php(C) Plan.php(©) ReportController.phpJiminnybeouecommana.ongAutomatedReportsCommand.php© AutomatedReportsSendCommand.phpC AddLayoutEntities.phpC) Team.phpC) AutomatedReportsRepository.php X) AutomatedReportsService.php© CreateHeldActivityEvent.phpe) Track?roviderinstalled-vent.onoC ActivityLogged.phpC RequestGenerateAskJiminnyReportJob.phpRequestGeneratekeportJob.ong© AutomatedReportResult.php© AutomatedReport.phpclass AutomatedReportsrepos1tory62A15 V4 ^-14* dreturn AutomatedReportpublic function create(array $data): AutomatedReport...* Find an automated report by UUID*dparam string suuld* drecurn Aurondredkeoorcnuupublic function findByUuid(string Suuid): ?AutomatedReportreturn AutomatedReport::where('uuid', AutomatedReport:: to0ptimized(Suuid))->firstO:Tusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReportif (is numeric(sidorluid)) "return Automacedkeport..tznal(1nt) s1auruu1a);return AutomatedReport::where('uvid', AutomatedReport::to0ptimized(Sid0rUuid))->firstO;* Retrieve all standard (non-Ask Jiminny) automated reports.* dparam string ssortcolumnThe column to sort by. Allowed values: 'created_by", 'created_at'. 46* dparam string SsortDirection The sort direction. Allowed values:"asc","desc". befaults to "des47* drerurn couuectonsaurondredredor*/12 usagespublic function getAllStandardReportsstring SsortColumn ="created_at',string SsortDirection = 'desc': Collection 1...*** Recrieve aLL Ask Jaminny reporus created Dy the given user.—57* dparam usersuserIne user wnose reporus to retrieve.*oparan scring esortho lunnIne cocumn co sorc by. Accowed vacues. createa_by!creaced_ar".xoocran saino osorcutreccion lne sorc anreccion. Accoyeo vocues.'asc'.'desc'. Defaults to 'dex 6e* dreturn Collection<AutomatedReport>14 usagesWinasurt changelog 2.12.21: A new version is avallable. |/ View Changelog (today 10:33)= custom.log= laravel.logL SF (iminny@localhostHs local liminnyalocalnostconsole PRODL console [EUl¿ consoe STAGINGI© AskJiminnyReportActivityService.php x©) AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpuseJlninny Models Acclvity seareh,useJiminny Models User:use Jiminny Repositories ElasticActivityRepository:use Jiminny VO Repository OnDemandActivitySearch\Criteria;use Psr\Log Loggerinterface;class ASKJ1minnyReportAct1vityserviceonvare const nt UEFAULI UP ACILEES CUUN = 100private const arrav DATE FILTER KEYS =AccIvLcyAccuaLbace..PARAM_SIAKI_UAlE.ActivityActualDate:: PARAM END DATE.ActivityUpdatedDate::PARAM_UPDATED_FROMActivityUpdatedDate::PARAM_UPDATED_TO.ClosingPer1odF1lter::KEY_START_DATE,ClosingPer1odF1lter::KEY_END_DATE,pubuic tunction __conscructlprivace readonly Aculviltysearch saccivitysearch,privace readonty clascicactiviсукeposicory selasucкepository.private readonty Loggerincertace +logger,Df...r*** Fetch activity IDs for a saved search, passing 1ts filters as-1s* Date filters stored on the saved search are excluded; 1f no othen* no date constraint 1s applied - matching the behaviour of getcont.* Oreturn string[] Activity IDspublic function getActivitvIdsForSavedSearchdSearch SsavedSearch.User suser,D: arraySrequestParams = Sthis->buildRequestParamsFromSearchSsavedSearc.scriteria = criteria::createrromrequestlAcceptmarьa-SrequestParams. "'Timit' => self::DEFAULT TOP AC1array_mergelsrequestrarams, L'Limlu => seLt::UEFAULI_10P_ACnuser-poernezone$filterSet = Sthis-›activitySearch->qetOnDemandPageFilterSet(ScriSactivityIds = sthis->elasticRepository->onDemandSearchlds0nly(Ssth1s->Logger->1nfolLAskJ1minnyReport) Fetched activity IDs fon=> ssavedSearch->getid)."user_1d = suser->gecia).=> count(SactivitvIds).1):Accept rlle ao+X Reject File 40 38 @* 1 of 2 files →, 0lablSupport Daily • in 2 h 54m100% |45]Tue 14 Apr 12:06:25RequestGenerateAsk.liminnvRenort.lob TestCascadeFixing ReportControlleAutomated Report Ma© Fixing Ask Jiminny FNow see tne Tul o clure, Lerme also check Activitvlurat ionkande ano Actwvitvkecorded ceauis or 1sFirstRequeseureReao Acuviyburauonkance ono ano Acrivivrecorcec.onoNow Inave tne comolere roo, cause o cture. nis s crucarKoot cause rounene oua lokequestraramsrromsearch mernocin Ask aminnvredortActvl vservice vasses sequence number=implicitly (not in params), which means isFirstRequest() returns true.When sequence number Is notin requestParams, the criteria:: createrromkequest delaulsitlo o, and 1sr1rstRequest() returns true when empty sequenceNumber == 0The frontend URL has sequence number=4 - meaning it's not a first request. The service doesn't set it, so thecriera thinks iu's atrstrecuestWhen isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. Activityburationkange — applies min_duration = 1 (INITIAL_MIN) - Tllters out U-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) - filters torecorded-ohly3. OrganiserGroupln - applies user's detault group filterbut the Trontend With sequence number=4 sklos all or these derauls, so it returns more resuits.The fix should be in bui ldRequestParamsFromsearch - it needs to pass sequence_number in the built params tosignal "not a first request", so the implicit defaults don't apply. Or alternatively, always pass a non-zero sequence number In tne merce in derAcuivlivlostorsaveNow let me verify my understanding of isFirstRequest :reao criera,onoConirmeo, Ine rixis cear ano minimar Une oetActivlvlosrorsavedsearch menoo neeos o oass sequence nurber with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.• Ask.Now let me check if there's an existing test for AskJiminnyReportActivityService to update:Explored AskJiminnyReportActivityServiceTest.php and searched AskJiminnyReportActivity*need to add a test that verifies sequence number=1 IS passed to Criteria (so 1sFirstRequest( returns false )Let me add it to the existing test file:• AskJ.LACIVILyoervicelestongNow ler's tun tne lestto verity.aосker Lamplpnp /var/www/ncml/drc1san lesytests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServicelest.php -=no-covelayeCould not open input file: /var/www/html/artisanCommand dockenO cocker exec vocker lano i ono aoparusan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php -=no-coverrageRun &+ Skip2 files with changestests/Unit/services/Klosk Automatedkenoris/AskJiminnvrenortActivivservicellest.onoView allapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (&+L)+ <> CodeClaude Sennet 4.6Wwinasur leamsuir-oia 4 spaces...
|
NULL
|
|
10983
|
217
|
48
|
2026-04-14T09:06:38.376524+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157598376_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelpProject vD AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph® ReportSort.php(e) Reporisonbirection.Kloskservice.php> M Mail• MeetingGenerator> D NotificationD OAuth2D RecallAl[ SecurityC StrategyStreamingD TeamTelephonyUserPilotM Webhook© AbstractService.php© ActivityProviderFactory.ph|©ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php©IntercomService.php©IpapiClient.phpIpapiService.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→IUTIS• I validation> D VOphp helpers.php© InitialFrontendState.php© Jiminny.php© Plan.php© ReportController.php© AutomatedReportsCommand.phpAddLayoutEntities.php© JiminnyDebugCommand.php© AutomatedReportsSendCommana.pnp• Team.php© AutomatedReportsRepository.php x© CreateHeldActivityEvent.phpC CreateActivityLoggedEvent.php(C) User?llorActiviv.istener.oho© ActivityLogged.php(©) AutomatedReportsCallbackService.php• RequestGenerateAskJiminnyReportJob.php© AutomatedReportResult.php© AutomatedReport.phpclass AutomatedReportsRepository(C) RequestGenerateReportJob.phpA15 V4^475152535456646574* dreturn AutomatedReportpublic function create(array $data): AutomatedReportf./*** Find an automated report by UUID* @param string $uvid* @return AutomatedReport/nullpublic function findByUuid(string $uuid): ?AUtomatedRep(33return AutomatedReport:: where('uuid', AutomatedRepor 3637-381 usagepublic function findById0rUuid(string $id0rUuid): ?Autonif (is_numeric($idOrUuid)) €return Automacedkeport..tznal(1nt) s1auruu1a);return AutomatedReport: :where('uvid', AutomatedRepor/*** Retrieve all standard (non-ASk Liminny) automated retso* @param string $sortColumnThe column to sort by. A* Oparam string $sortDirection The sort direction. AllC51* Oreturn Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Ziminny reports created by the giver 62* @param UsersusenThe user whose reports 164*oodrdl sarno osorccocuminIne cocumn co sorc Dy. ·65* Oparam string $sortDirection The sort direction. AllC66Windsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)= custom.log= laravel.logA SF [jiminny@localhost]L console [STAGING]© AskJiminnyReportActivityService.php xRequestGenerateAskJiminnyReportJobTest.phpuse Jiminny\Models\Activity\Search;useJiminny\Models \User;use Jiminny\Repositories\ElasticActivityRepository;use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;usePsr\Log\LoggerInterface;A HS_local [jiminny@localhost]Al console [PROD]© AskJiminnyReportActivityServiceTest.phpA console (EU]class asкуладукерorcaccvicyserviceprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;private const array [ENV_SECRET],ActivityActualDate: :PARAM_END_DATE,ActivityUpdatedDate: :PARAM_UPDATED_FROM,ActivityUpdatedDate::PARAM_UPDATED_TO,ClosingPeriodFilter::KEY_START_DATE,closingrer1odrilter..KEY_ENU_bAlE,public function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,0 {...3/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilter.* Oreturn string[] Activity IDspublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(Acceptmagze ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1]),array_merge($requestParams, ['Limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => A,'sequence_numb$user->getTimezone()$filterSet = $this-›activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filterSet);nunus-> looder>info('lAskJiminnxRepont] Fetched activity IDsfor saved search'.→> $savedSearch->getId(),'user id' => Suser->qetIdo.'activity_count' => count($activityIds),ID:return SactivityIds;V Accept File *+X Reject File 0 38@€ 1 of 2 files →, 0lablSupport Daily - in 2h 54mA100% |45]Tue 14 Apr 12:06:37RequestGenerateAsk.liminnvRenort.lob TestCascadeFixing ReportControlleAutomated Report Ma© Fixing Ask Jiminny R+D ...Now see tne Tul o clure, Lerme also check Activitvlurat ionkande ano Actwvitvkecorded ceauis or 1sFirstRwequeseuy.Reao Acuiviyburauonkance ono ano Actvivrecorcec.onoNow Inave tne comolere roo, cause o cture. nis s crucarRoot Cause Foundne oua lokequestraramsrromsearch mernocin Ask aminnvredortActvl vservice vasses sequence number=implicitly (not in params), which means isFirstRequest() returns true.When sequence number Is notin requestParams, the criteria:: createrromkequest delaulsitlo o, and 1sr1rstRequest() returns true when empty || sequenceNumber === 0.The frontend URL has sequence_number=4 — meaning it's not a first request. The service doesn't set it, so thecriera thinks iu's atistrecuestWhen isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. Activityburationkange — applies min_duration = 1 (INITIAL_MIN) - Tllters out U-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters torecorded-ohly3. OrganiserGroupIn - applies user's default group filterbut the Trontend With sequence number=4 sklos all or these derauls, so it returns more resuits.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params tosignal "not a first request", so the implicit defaults don't apply. Or alternatively, always pass a non-zero sequence_number In tne merce in derAcuivlivlostorsaveNow let me verify my understanding of isFirstRequest:reao criera,onoConirmeo, Ine rixis cear ano minimar Une oetActivlvlosrorsavedsearch menoo neeos o oass sequence nurber with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.• Ask.Now let me check if there's an existing test for AskJiminnyReportActivityService to update:Explored AskJiminnyReportActivityServiceTest.php and searched AskJiminnyReportActivity*I need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ).Let me add it to the existing test file:• AskJ.RACIViLyoervicelestoneNow ler's tun tne lestto verity.exeddocker_lamp_pnp /var/www/ncml/drc1san lesytests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServicelest.php --no-covelayeCould not open input file: /var/www/html/artisanCommand dockeno cocker execoocker lano " ono aoparusan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverrageRun a8+ (Skip2 files with changestests/Unit/services/Klosk AutomateckeporisAsk.iminnvrenortActivivservicellest.onoapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1View allReject allAccept allAsk anything (2*L)+ <> CodeClaude Sonnet 4.6winasur leamsuir-o( 4 spaces...
|
NULL
|
-6823678993976724559
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelpProject vD AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph® ReportSort.php(e) Reporisonbirection.Kloskservice.php> M Mail• MeetingGenerator> D NotificationD OAuth2D RecallAl[ SecurityC StrategyStreamingD TeamTelephonyUserPilotM Webhook© AbstractService.php© ActivityProviderFactory.ph|©ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php©IntercomService.php©IpapiClient.phpIpapiService.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→IUTIS• I validation> D VOphp helpers.php© InitialFrontendState.php© Jiminny.php© Plan.php© ReportController.php© AutomatedReportsCommand.phpAddLayoutEntities.php© JiminnyDebugCommand.php© AutomatedReportsSendCommana.pnp• Team.php© AutomatedReportsRepository.php x© CreateHeldActivityEvent.phpC CreateActivityLoggedEvent.php(C) User?llorActiviv.istener.oho© ActivityLogged.php(©) AutomatedReportsCallbackService.php• RequestGenerateAskJiminnyReportJob.php© AutomatedReportResult.php© AutomatedReport.phpclass AutomatedReportsRepository(C) RequestGenerateReportJob.phpA15 V4^475152535456646574* dreturn AutomatedReportpublic function create(array $data): AutomatedReportf./*** Find an automated report by UUID* @param string $uvid* @return AutomatedReport/nullpublic function findByUuid(string $uuid): ?AUtomatedRep(33return AutomatedReport:: where('uuid', AutomatedRepor 3637-381 usagepublic function findById0rUuid(string $id0rUuid): ?Autonif (is_numeric($idOrUuid)) €return Automacedkeport..tznal(1nt) s1auruu1a);return AutomatedReport: :where('uvid', AutomatedRepor/*** Retrieve all standard (non-ASk Liminny) automated retso* @param string $sortColumnThe column to sort by. A* Oparam string $sortDirection The sort direction. AllC51* Oreturn Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Ziminny reports created by the giver 62* @param UsersusenThe user whose reports 164*oodrdl sarno osorccocuminIne cocumn co sorc Dy. ·65* Oparam string $sortDirection The sort direction. AllC66Windsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)= custom.log= laravel.logA SF [jiminny@localhost]L console [STAGING]© AskJiminnyReportActivityService.php xRequestGenerateAskJiminnyReportJobTest.phpuse Jiminny\Models\Activity\Search;useJiminny\Models \User;use Jiminny\Repositories\ElasticActivityRepository;use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;usePsr\Log\LoggerInterface;A HS_local [jiminny@localhost]Al console [PROD]© AskJiminnyReportActivityServiceTest.phpA console (EU]class asкуладукерorcaccvicyserviceprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;private const array [ENV_SECRET],ActivityActualDate: :PARAM_END_DATE,ActivityUpdatedDate: :PARAM_UPDATED_FROM,ActivityUpdatedDate::PARAM_UPDATED_TO,ClosingPeriodFilter::KEY_START_DATE,closingrer1odrilter..KEY_ENU_bAlE,public function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,0 {...3/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilter.* Oreturn string[] Activity IDspublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(Acceptmagze ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1]),array_merge($requestParams, ['Limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => A,'sequence_numb$user->getTimezone()$filterSet = $this-›activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filterSet);nunus-> looder>info('lAskJiminnxRepont] Fetched activity IDsfor saved search'.→> $savedSearch->getId(),'user id' => Suser->qetIdo.'activity_count' => count($activityIds),ID:return SactivityIds;V Accept File *+X Reject File 0 38@€ 1 of 2 files →, 0lablSupport Daily - in 2h 54mA100% |45]Tue 14 Apr 12:06:37RequestGenerateAsk.liminnvRenort.lob TestCascadeFixing ReportControlleAutomated Report Ma© Fixing Ask Jiminny R+D ...Now see tne Tul o clure, Lerme also check Activitvlurat ionkande ano Actwvitvkecorded ceauis or 1sFirstRwequeseuy.Reao Acuiviyburauonkance ono ano Actvivrecorcec.onoNow Inave tne comolere roo, cause o cture. nis s crucarRoot Cause Foundne oua lokequestraramsrromsearch mernocin Ask aminnvredortActvl vservice vasses sequence number=implicitly (not in params), which means isFirstRequest() returns true.When sequence number Is notin requestParams, the criteria:: createrromkequest delaulsitlo o, and 1sr1rstRequest() returns true when empty || sequenceNumber === 0.The frontend URL has sequence_number=4 — meaning it's not a first request. The service doesn't set it, so thecriera thinks iu's atistrecuestWhen isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. Activityburationkange — applies min_duration = 1 (INITIAL_MIN) - Tllters out U-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters torecorded-ohly3. OrganiserGroupIn - applies user's default group filterbut the Trontend With sequence number=4 sklos all or these derauls, so it returns more resuits.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params tosignal "not a first request", so the implicit defaults don't apply. Or alternatively, always pass a non-zero sequence_number In tne merce in derAcuivlivlostorsaveNow let me verify my understanding of isFirstRequest:reao criera,onoConirmeo, Ine rixis cear ano minimar Une oetActivlvlosrorsavedsearch menoo neeos o oass sequence nurber with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.• Ask.Now let me check if there's an existing test for AskJiminnyReportActivityService to update:Explored AskJiminnyReportActivityServiceTest.php and searched AskJiminnyReportActivity*I need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ).Let me add it to the existing test file:• AskJ.RACIViLyoervicelestoneNow ler's tun tne lestto verity.exeddocker_lamp_pnp /var/www/ncml/drc1san lesytests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServicelest.php --no-covelayeCould not open input file: /var/www/html/artisanCommand dockeno cocker execoocker lano " ono aoparusan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverrageRun a8+ (Skip2 files with changestests/Unit/services/Klosk AutomateckeporisAsk.iminnvrenortActivivservicellest.onoapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1View allReject allAccept allAsk anything (2*L)+ <> CodeClaude Sonnet 4.6winasur leamsuir-o( 4 spaces...
|
NULL
|
|
10985
|
217
|
49
|
2026-04-14T09:06:41.417828+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157601417_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.76171875,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.7796875,"top":0.017361112,"width":0.12109375,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"bounds":{"left":0.38867188,"top":0.0,"width":0.41015625,"height":1.0},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.32460937,"top":0.23819445,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.33828124,"top":0.23819445,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.34960938,"top":0.23680556,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3582031,"top":0.23680556,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"bounds":{"left":0.15234375,"top":0.04097222,"width":0.39882812,"height":0.95902777},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
4414873592361684168
|
-5968484087913173388
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
10983
|
|
10988
|
216
|
28
|
2026-04-14T09:07:30.523138+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157650523_m1.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
+SlackFileEditViewGoHistoryWindowHelpEDHomeDMsActi +SlackFileEditViewGoHistoryWindowHelpEDHomeDMsActivityFilesLater..•More+Jiminny ...sos# Starred8platform-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...R. Adelina PetrovaO. Cala 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 GeorgievAa>0 lhl§ Support Daily • in 2h 53 m100% <*Tue 14 Apr 12:07:3084Today ~New...
|
NULL
|
2718577051973848984
|
NULL
|
visual_change
|
ocr
|
NULL
|
+SlackFileEditViewGoHistoryWindowHelpEDHomeDMsActi +SlackFileEditViewGoHistoryWindowHelpEDHomeDMsActivityFilesLater..•More+Jiminny ...sos# Starred8platform-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...R. Adelina PetrovaO. Cala 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 GeorgievAa>0 lhl§ Support Daily • in 2h 53 m100% <*Tue 14 Apr 12:07:3084Today ~New...
|
NULL
|
|
10989
|
216
|
29
|
2026-04-14T09:07:33.523421+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157653523_m1.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
+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 53 m100% <47Tue 14 Apr 12:07:338Today ~...
|
NULL
|
6728278616929760394
|
NULL
|
visual_change
|
ocr
|
NULL
|
+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 53 m100% <47Tue 14 Apr 12:07:338Today ~...
|
10988
|
|
10993
|
217
|
52
|
2026-04-14T09:07:45.027562+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157665027_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodelaravePetactonTool PhpStormFileFditViewNavigateCodelaravePetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.php= custom.lod= laravel.logL SF (iminny@localhostc HS_local fiminny@localhostL console (PROD]& console (EU]L console (STAGINGD Unit>DActions> Component› Configuration> MConsoleM ContractsM DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobtcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListenersC AutomatedReportsCommand.phpC AutomatedReportsSendCommand.phpC) AskJiminnyReportActivityService.phpC) AskJiminnyReportActivityServiceTest.php x C) RequestGenerateAskJiminnyReportJobTest.phpAddLayoutentities.php(C) Team.nho© AutomatedReportsRepository.php X© CreateHeldActivityEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivate LoggerinterfacexMock0bect slogger9 usagesC CreateActivityLoggedEvent.phpprivate AskJ1minnykeporcAculVityservice sservice;(C) Activtv odded.nnr29 GT>protected function setUp(: voidf...c) AutomatedRenorscalloackoerwce.onvC) RequestGenerateaskJiminnykeportJob.ono1l usages(©) RequestGenerateReportJob.phpAuLomaleakeportkesult.onoprivate function makeFilter(string Skey. ?string $value): SearchFilter&Mock0bject...h© AutomatedReport.phpclass AutomatedReportsrepos1toryo usaees> MModelsM Notifications› M ObserversPoliciesProvidersRepositoriesD Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c AutomatedRenorA15 V4 ^private function makeUsero: UserxMockobject...h* dreturn AutomatedReport8 usagesprivate runcuion makesavedsearcn(array prilters): searchomockudjeccl...spublic function create(array $data): AutomatedReport...71 M >public function testGetActivityIdsForSavedSearchReturnsIds: voidf...}* Find an automated report by UUID100 M >public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(: voidt...}* dparam string $uu1d118 M >public function testGetActivityldsFilters0utDateFiltersO: voidk...h*dreturn AutomatedReportnul7public function findByUuid(string Suuid): ?AutomatedReport157 % >184185 ₽ >public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandlesArrayFilters(): void{...}return AutomatedReport::where('uuid', AutomatedReport::toOptim.206 6)public function testGetActivityIdsHandlesScalarFilters(: void{...}Tusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReportif (is_numeric($id0rUuid)) {225 h Pun 'testGetActivitvldsPaO- Debug 'testGetActivityldsPa...'( Run 'testGetActivitvidsPa...' with CoverageModify Run Configuration….PassesNonZeroSequenceNumberToDisableFirstRequestDefaultsQ: void228229230edSearch([]) ;sfilterSet = sthis-›createMock( originalClassName: FilterDefinitionCollection::class):sthis->activitysearch->method( constraint:'getArrayr1lterKeys')->w1LLReturn(LJD:lreturn AutomatedReport::where('uvid', AutomatedReport::to0ptim.Ncaoruredtrtertae nuuu/*** Retrieve all standard (non-Ask Jiminny) automated reports.ani S->acuwVsearch-sexdectsiun S->once u→>iecno constraind'getOnDemandPageFilterSet')-LurerurnlacLoacku runculon(Criteria $criteria) use ($filterSet, &$capturedCriteria) {...F);* dparam string ssortcolumnThe column to sort by. Allowed vaz 242* dparam string ssortuireccion ine sorc direccion. ALlowed values* drerurn cocuectonsaurondredredor»12 usagespublic function getAllStandardReportsstring SsortColumn ="created_at',string SsortDirection =desc: Collection 1.245245— 246247248— 249250_231252 M >$this-›elasticRepository->method( constraint:'onDemandSearchldsonly')->willReturn(LJD:sthis->Loggen->method constraint: "info'D:sthis->service->getActiv1tyudsForsavedsearch(ssavedsearch,suser);sthis->assertNotnulu(scapturedcriter1a)punis->assercralsel.capcureacriter1a->1srirsckequescoohpublic function testGetActivitvIdsLogsWithCorrectContext@: voidf..../*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam userIne user wnose reporus to retrieve*oodrdl sarno osorccocuminIne couin co sorc ou. Accowed vou* dparam string SsortDirection The sort direction. Allowed values1 eal/ Accept File &+X Reject File 1%g+ 2 of 2 files →Winasun ch. // View Changelog (today 10:33)AcceotRenect: Support Daily • in 2 h 53 m100% [2Tue 14 Apr 12:07:44RequestGenerateAskJiminnyReportJobTest vCascade†ControlleAutomated Renort Mal© Fixing Ask Jiminny FNow I nave the complele root cause picture. Inis is criucal:Poot calce SallndlIne ous lokequestraranst romsearch metnoe in Askudminnykeportactiv.tyService passes sequence number=" Implicitv not in params. whichimeals esrerstnequestly retums trueWhen sequence number Is notin requestParams, the criteria:: createrromRequest detaults itto 0, and isFirstRequest() returns true when emptysequencenumberThe frontend URL has sequence number=4 — meanina it's not a firstrequest. The service doesn't set it, so the criteria thinks it's a first request.wnen 1srirstkeouest = chue, tnese lmpllcit tlters are agglled tnalaren 't in the saved search1. ActivityDurationRange — applies min_duration = 1 (INITIAL_MIN)- filters out 0-second calls%AcIIvlivrecorded — adoles only recorded = 1 D--AULI VALUE=OPTION_RECORDED) - filters to recorded-onlyOrganiserGroupIn — applies user's default group filterburthe Tronteno Wiun sequence numberza skiosalll ortnese ceaulis. soitretums more resullsIne tix snoule oe in bur lakequestraranstrombearch - lneeas lo pass sequence number in the oult params to sicnal "not a first recuest" so theimplicit defaults don't apply. Or alternatively, always pass a non-zero sequence number in the merge in gecactivitylasrorsavedsearch.Read As.Now let me verify my understanding of isFirstRequest :reao crieraoneContirmed. The fix is clear and minimal. Tine detActivirvidsForsavedSearich method needs to pass sequence number with a non-zero value so that 1srirstrequesc returns talse ane no imolicit aeraults are apollea1 ASkJInNow let me check ir there's an existing test for AskJiminnykeportActivityService to update:Explorea AskJiminnykepor Activilyservicelest.ono and searched ASkJl..Ineed lo add a lest thau verities sequence number=l is passed to criceriaso 1sFirstRequestlo returns false ). Ler me add It to the existine testi• AskJiminnyReportActivityServiceTest.phpNow ler's run the lestto verity.docker exec docker lamp 1 php /var/www/html/artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyRepo"enceevalyoet veccteotephrTurcovelayeCould not open input file: /var/www/html/artisanCommand docken•docker exec aockerdocker_Lamp_1 php /app/artisanView all.sk/AutomatedReports/@ AskJiminnvReportActivitvServiceTest.phv +27.../Kiosk/AutomatedReports/D AskJiminnyReportActivityService.phpReject allAccept allAsk anything (&+L)+ ‹› CodeClaude Sonnet 4.6winasun leamsuir-oia 4 spacesW...
|
NULL
|
-2957561828763719742
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodelaravePetactonTool PhpStormFileFditViewNavigateCodelaravePetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.php= custom.lod= laravel.logL SF (iminny@localhostc HS_local fiminny@localhostL console (PROD]& console (EU]L console (STAGINGD Unit>DActions> Component› Configuration> MConsoleM ContractsM DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobtcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListenersC AutomatedReportsCommand.phpC AutomatedReportsSendCommand.phpC) AskJiminnyReportActivityService.phpC) AskJiminnyReportActivityServiceTest.php x C) RequestGenerateAskJiminnyReportJobTest.phpAddLayoutentities.php(C) Team.nho© AutomatedReportsRepository.php X© CreateHeldActivityEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivate LoggerinterfacexMock0bect slogger9 usagesC CreateActivityLoggedEvent.phpprivate AskJ1minnykeporcAculVityservice sservice;(C) Activtv odded.nnr29 GT>protected function setUp(: voidf...c) AutomatedRenorscalloackoerwce.onvC) RequestGenerateaskJiminnykeportJob.ono1l usages(©) RequestGenerateReportJob.phpAuLomaleakeportkesult.onoprivate function makeFilter(string Skey. ?string $value): SearchFilter&Mock0bject...h© AutomatedReport.phpclass AutomatedReportsrepos1toryo usaees> MModelsM Notifications› M ObserversPoliciesProvidersRepositoriesD Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c AutomatedRenorA15 V4 ^private function makeUsero: UserxMockobject...h* dreturn AutomatedReport8 usagesprivate runcuion makesavedsearcn(array prilters): searchomockudjeccl...spublic function create(array $data): AutomatedReport...71 M >public function testGetActivityIdsForSavedSearchReturnsIds: voidf...}* Find an automated report by UUID100 M >public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(: voidt...}* dparam string $uu1d118 M >public function testGetActivityldsFilters0utDateFiltersO: voidk...h*dreturn AutomatedReportnul7public function findByUuid(string Suuid): ?AutomatedReport157 % >184185 ₽ >public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandlesArrayFilters(): void{...}return AutomatedReport::where('uuid', AutomatedReport::toOptim.206 6)public function testGetActivityIdsHandlesScalarFilters(: void{...}Tusdyepublic function findByldorUu1d(string s1d0rUu1d): ?AutomatedReportif (is_numeric($id0rUuid)) {225 h Pun 'testGetActivitvldsPaO- Debug 'testGetActivityldsPa...'( Run 'testGetActivitvidsPa...' with CoverageModify Run Configuration….PassesNonZeroSequenceNumberToDisableFirstRequestDefaultsQ: void228229230edSearch([]) ;sfilterSet = sthis-›createMock( originalClassName: FilterDefinitionCollection::class):sthis->activitysearch->method( constraint:'getArrayr1lterKeys')->w1LLReturn(LJD:lreturn AutomatedReport::where('uvid', AutomatedReport::to0ptim.Ncaoruredtrtertae nuuu/*** Retrieve all standard (non-Ask Jiminny) automated reports.ani S->acuwVsearch-sexdectsiun S->once u→>iecno constraind'getOnDemandPageFilterSet')-LurerurnlacLoacku runculon(Criteria $criteria) use ($filterSet, &$capturedCriteria) {...F);* dparam string ssortcolumnThe column to sort by. Allowed vaz 242* dparam string ssortuireccion ine sorc direccion. ALlowed values* drerurn cocuectonsaurondredredor»12 usagespublic function getAllStandardReportsstring SsortColumn ="created_at',string SsortDirection =desc: Collection 1.245245— 246247248— 249250_231252 M >$this-›elasticRepository->method( constraint:'onDemandSearchldsonly')->willReturn(LJD:sthis->Loggen->method constraint: "info'D:sthis->service->getActiv1tyudsForsavedsearch(ssavedsearch,suser);sthis->assertNotnulu(scapturedcriter1a)punis->assercralsel.capcureacriter1a->1srirsckequescoohpublic function testGetActivitvIdsLogsWithCorrectContext@: voidf..../*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam userIne user wnose reporus to retrieve*oodrdl sarno osorccocuminIne couin co sorc ou. Accowed vou* dparam string SsortDirection The sort direction. Allowed values1 eal/ Accept File &+X Reject File 1%g+ 2 of 2 files →Winasun ch. // View Changelog (today 10:33)AcceotRenect: Support Daily • in 2 h 53 m100% [2Tue 14 Apr 12:07:44RequestGenerateAskJiminnyReportJobTest vCascade†ControlleAutomated Renort Mal© Fixing Ask Jiminny FNow I nave the complele root cause picture. Inis is criucal:Poot calce SallndlIne ous lokequestraranst romsearch metnoe in Askudminnykeportactiv.tyService passes sequence number=" Implicitv not in params. whichimeals esrerstnequestly retums trueWhen sequence number Is notin requestParams, the criteria:: createrromRequest detaults itto 0, and isFirstRequest() returns true when emptysequencenumberThe frontend URL has sequence number=4 — meanina it's not a firstrequest. The service doesn't set it, so the criteria thinks it's a first request.wnen 1srirstkeouest = chue, tnese lmpllcit tlters are agglled tnalaren 't in the saved search1. ActivityDurationRange — applies min_duration = 1 (INITIAL_MIN)- filters out 0-second calls%AcIIvlivrecorded — adoles only recorded = 1 D--AULI VALUE=OPTION_RECORDED) - filters to recorded-onlyOrganiserGroupIn — applies user's default group filterburthe Tronteno Wiun sequence numberza skiosalll ortnese ceaulis. soitretums more resullsIne tix snoule oe in bur lakequestraranstrombearch - lneeas lo pass sequence number in the oult params to sicnal "not a first recuest" so theimplicit defaults don't apply. Or alternatively, always pass a non-zero sequence number in the merge in gecactivitylasrorsavedsearch.Read As.Now let me verify my understanding of isFirstRequest :reao crieraoneContirmed. The fix is clear and minimal. Tine detActivirvidsForsavedSearich method needs to pass sequence number with a non-zero value so that 1srirstrequesc returns talse ane no imolicit aeraults are apollea1 ASkJInNow let me check ir there's an existing test for AskJiminnykeportActivityService to update:Explorea AskJiminnykepor Activilyservicelest.ono and searched ASkJl..Ineed lo add a lest thau verities sequence number=l is passed to criceriaso 1sFirstRequestlo returns false ). Ler me add It to the existine testi• AskJiminnyReportActivityServiceTest.phpNow ler's run the lestto verity.docker exec docker lamp 1 php /var/www/html/artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyRepo"enceevalyoet veccteotephrTurcovelayeCould not open input file: /var/www/html/artisanCommand docken•docker exec aockerdocker_Lamp_1 php /app/artisanView all.sk/AutomatedReports/@ AskJiminnvReportActivitvServiceTest.phv +27.../Kiosk/AutomatedReports/D AskJiminnyReportActivityService.phpReject allAccept allAsk anything (&+L)+ ‹› CodeClaude Sonnet 4.6winasun leamsuir-oia 4 spacesW...
|
NULL
|
|
10995
|
217
|
53
|
2026-04-14T09:07:51.093583+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157671093_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactorToo PhpStormFileFditViewNavigateCodeLaravelRetactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.php= custom.log= laravel.logL SF (iminny@localhostc HS_local fiminny@localhostL console (PROD]& console (EU]L console (STAGINGD Unit_ ActionsComponent› ConfigurationM ConsoleM ContractsM DomainD DTO• Enums_ Events_ Exceptions→ fixturesD Helpers_ Http>_Integrations> MinteractionsMJobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl© AutomatedReportsCommand.phpC AutomatedReportsSendCommand.phpC AskJiminnyReportActivityService.phpC) AskJiminnyReportActivityServiceTest.php x C) RequestGenerateAskJiminnyReportJobTest.phpAddLayoutentities.php(C) Team.nho© AutomatedReportsRepository.php x© CreateHeldActivityEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivate LoggerinterfacexMock0bect slogger9 usagesC CreateActivityLoggedEvent.phpprivate AskJ1minnykeporcAculVityservice sservice;(C) Activtv odded.nnr29 GT>protected function setUp(: voidf...c) AutomatedRenorscalloackoerwce.onvC) RequestGenerateaskJiminnykeportJob.ong1l usages(©) RequestGenerateReportJob.php(C) AutomatedReportResult.phpprivate function makeFilter(string Skey. ?string $value): SearchFilter&Mock0bject...h© AutomatedReport.phpclass AutomatedReportsrepos1toryo usaees(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordin(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications› M ObserversD PoliciesProvidersRepositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyReporA15 V4^private function makeUsero: UserxMockobject...h* dreturn AutomatedReportpublic function create(array $data): AutomatedfRunAAskJiminnyReportActivityServiceTest.testGetActivityldsPasse..GGGUGKOA* Find an automated report by UUIDv * Running tests...v *- CLI Arguments* dparam string $uu1d> * Tests(Unit(Services\Kiosk\AutomatedReports\AsKJiminnyReportActivityServiceTest*dreturn AutomatedReportnul7public function findByUuid(string Suuid): ?Autcreturn AutomatedReport::where('uuid', Auton0 test passed 0/1 testsTusdyepublic function findbyldoruu1d(string s1d0rUulcif (is_numeric($id0rUuid)) {return Aucomacedkeport:.tznal(1nt) $1dlreturn AutomatedReport::where(('uuid'. Auton/*** Retrieve all standard (non-Ask Jaminny) autc* dparam string ssortcolumnThe column to s* dparam string ssortulreccion ine sort direct* drerurn couuectonsaurondredredor12 usagespublic function getAllStandardReportsstring SsortColumn E"created_at',string SsortDirection =desc: Collection 1./*** Recrieve aLL Ask Jaminny reporus created Dy tne given user.* dparam usersuserIne user wnose reporus to retrieve*oodrdl sarno osorccocuminIne cocuin co sorc ou. Accowed vou1 eallv Accept File *~ X Reject File + 38 €* 2 of 2 files →(c AutomatedRenor* dparam string SsortDirection The sort direction. Allowed valuesWinasur change. // View Changelog (today 10:33)a Support Daily • in 2 h 53 m100% |45]Tue 14 Apr 12:07:50L AskJiminnyReportActivityServiceT..DefaultsCascade*ControlleAutomated Renort Mal© Fixing Ask Jiminny Fmrequest eauisirod ano 1sFirstreovesto reurs true when emotyseouencenunbelThe frontend URL has sequence number=4 — meaning it's not a firstreduest, Tihe service doesn't ser lt, so the criteria thinks it's a first reduest.When isFirstRequest() = true , these implicit filters are applied thataren tin the saveo search1. ActivityionRanae — applies min duration = 1 (INITIAL MIN)— Tllters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE =OPTION_RECORDED) — filters to recorded-onlyOrganiserGroupin — applies user's default group filterbut the Trontend With sequence number=4 sklos all or these deraults, soitreturns more resultsyequestraransrrombearch — it neeas to pass soarams lo sional "nota Tistrecuest", so the: Or alternatively, always pass a non-zero sequevecactivitylosrorsavecsearchstanding of isfirstRequest:no minimar Une oetActivlvlosrorsavedseanequence_number with a non-zero value so that 1False and no implicit defaults are appliedan existine lesttor AskuiminnукeporLaccivicyMes sequence numderet is passeeto cricerlains talse)rlerme acc Tto tne ex sune lestlyservicelestongphp /var/www/html/artisan test/Kiosk/AutomatedReports/AskJiminnyRepost.phpno-coverayertlle. var ww htmyartisanlamp 1 php /app/artisan test/Kiosk/AutomatedReports/AskJiminnyReposleone -no-covelayeRun 88+ SkipView allJskJiminnvReportActivitvServiceTest.phv +27./Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php+1 -1Reject allAccept allAsk anything (&+L)+ <› Code.Claude Sonnet 4.6winasun leamsZ45uir-oia 4 spaces...
|
NULL
|
-3417829161379963207
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactorToo PhpStormFileFditViewNavigateCodeLaravelRetactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.php= custom.log= laravel.logL SF (iminny@localhostc HS_local fiminny@localhostL console (PROD]& console (EU]L console (STAGINGD Unit_ ActionsComponent› ConfigurationM ConsoleM ContractsM DomainD DTO• Enums_ Events_ Exceptions→ fixturesD Helpers_ Http>_Integrations> MinteractionsMJobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl© AutomatedReportsCommand.phpC AutomatedReportsSendCommand.phpC AskJiminnyReportActivityService.phpC) AskJiminnyReportActivityServiceTest.php x C) RequestGenerateAskJiminnyReportJobTest.phpAddLayoutentities.php(C) Team.nho© AutomatedReportsRepository.php x© CreateHeldActivityEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivate LoggerinterfacexMock0bect slogger9 usagesC CreateActivityLoggedEvent.phpprivate AskJ1minnykeporcAculVityservice sservice;(C) Activtv odded.nnr29 GT>protected function setUp(: voidf...c) AutomatedRenorscalloackoerwce.onvC) RequestGenerateaskJiminnykeportJob.ong1l usages(©) RequestGenerateReportJob.php(C) AutomatedReportResult.phpprivate function makeFilter(string Skey. ?string $value): SearchFilter&Mock0bject...h© AutomatedReport.phpclass AutomatedReportsrepos1toryo usaees(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordin(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications› M ObserversD PoliciesProvidersRepositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyReporA15 V4^private function makeUsero: UserxMockobject...h* dreturn AutomatedReportpublic function create(array $data): AutomatedfRunAAskJiminnyReportActivityServiceTest.testGetActivityldsPasse..GGGUGKOA* Find an automated report by UUIDv * Running tests...v *- CLI Arguments* dparam string $uu1d> * Tests(Unit(Services\Kiosk\AutomatedReports\AsKJiminnyReportActivityServiceTest*dreturn AutomatedReportnul7public function findByUuid(string Suuid): ?Autcreturn AutomatedReport::where('uuid', Auton0 test passed 0/1 testsTusdyepublic function findbyldoruu1d(string s1d0rUulcif (is_numeric($id0rUuid)) {return Aucomacedkeport:.tznal(1nt) $1dlreturn AutomatedReport::where(('uuid'. Auton/*** Retrieve all standard (non-Ask Jaminny) autc* dparam string ssortcolumnThe column to s* dparam string ssortulreccion ine sort direct* drerurn couuectonsaurondredredor12 usagespublic function getAllStandardReportsstring SsortColumn E"created_at',string SsortDirection =desc: Collection 1./*** Recrieve aLL Ask Jaminny reporus created Dy tne given user.* dparam usersuserIne user wnose reporus to retrieve*oodrdl sarno osorccocuminIne cocuin co sorc ou. Accowed vou1 eallv Accept File *~ X Reject File + 38 €* 2 of 2 files →(c AutomatedRenor* dparam string SsortDirection The sort direction. Allowed valuesWinasur change. // View Changelog (today 10:33)a Support Daily • in 2 h 53 m100% |45]Tue 14 Apr 12:07:50L AskJiminnyReportActivityServiceT..DefaultsCascade*ControlleAutomated Renort Mal© Fixing Ask Jiminny Fmrequest eauisirod ano 1sFirstreovesto reurs true when emotyseouencenunbelThe frontend URL has sequence number=4 — meaning it's not a firstreduest, Tihe service doesn't ser lt, so the criteria thinks it's a first reduest.When isFirstRequest() = true , these implicit filters are applied thataren tin the saveo search1. ActivityionRanae — applies min duration = 1 (INITIAL MIN)— Tllters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE =OPTION_RECORDED) — filters to recorded-onlyOrganiserGroupin — applies user's default group filterbut the Trontend With sequence number=4 sklos all or these deraults, soitreturns more resultsyequestraransrrombearch — it neeas to pass soarams lo sional "nota Tistrecuest", so the: Or alternatively, always pass a non-zero sequevecactivitylosrorsavecsearchstanding of isfirstRequest:no minimar Une oetActivlvlosrorsavedseanequence_number with a non-zero value so that 1False and no implicit defaults are appliedan existine lesttor AskuiminnукeporLaccivicyMes sequence numderet is passeeto cricerlains talse)rlerme acc Tto tne ex sune lestlyservicelestongphp /var/www/html/artisan test/Kiosk/AutomatedReports/AskJiminnyRepost.phpno-coverayertlle. var ww htmyartisanlamp 1 php /app/artisan test/Kiosk/AutomatedReports/AskJiminnyReposleone -no-covelayeRun 88+ SkipView allJskJiminnvReportActivitvServiceTest.phv +27./Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php+1 -1Reject allAccept allAsk anything (&+L)+ <› Code.Claude Sonnet 4.6winasun leamsZ45uir-oia 4 spaces...
|
10993
|
|
10998
|
217
|
55
|
2026-04-14T09:07:57.383943+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157677383_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodelaravePetactonTool PhpStormFileFditViewNavigateCodelaravePetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.phpD Unit>DActions> Component› Configuration> MConsoleM ContractsM DomainD DTO• Enums_Events_ Exceptions© AutomatedReportsCommand.phpC AutomatedReportsSendCommand.phpAddLayoutentities.php(C) Team.nho© AutomatedReportsRepository.php X© CreateHeldActivityEvent.phpC CreateActivityLoggedEvent.php(C) Activtv odded.nnrc) AutomatedRenorscalloackoelvice.onvC RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.phpAuLomaleakeportkesult.ono© AutomatedReport.php→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitvclass AutomatedReportsrepos1toryA15 X4 ^> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobtcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications› M ObserversPoliciesProvidersRepositoriesD Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c AutomatedRenor* dreturn AutomatedReportpublic function create(array $data): AutomatedReport...71 M >* Find an automated report by UUID100 M ›* dparam string $uu1dAM9 MAY*dreturn AutomatedReportnul7157 A>public function findByUuid(string Suuid): ?AutomatedReport185 ₴)return AutomatedReport::where('uuid', AutomatedReport::toOptim.206 6)Tusdye225public function findbyldorUu1d(string s1d0rUu1d): ?Automatedreport227if (is_numeric($id0rUuid)) {return AutomatedReport::find((int) $id0rUuid);229236return AutomatedReport::where('uvid', AutomatedReport::to0ptim./*** Retrieve all standard (non-Ask Jaminny) automated reports.* dparam string ssortcolumnThe column to sort by. Allowed vaz 242* dparam string ssortuireccion ine sorc direccion. ALlowed values244245* drerurn cocuectonsaurondredredor»12 usagespublic function getAllStandardReports(247248string SsortColumn ="created_at',256string SsortDirection =desc): Collection 1.252 M >/*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam userThe user whose reports to retrieve*oodrdl sarno osorccocuminIne cocuin co sorc ou. Accowed vou* dparam string SsortDirection The sort direction. Allowed valuesWinasun ch. // View Changelog (today 10:33)E custom.loc= laravel.logL SF liminny@localhostc HS_local fiminny@localhostconcole DPOlbllL console (EU]L console (STAGINGC) AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php x C RequestGenerateAskJiminnyReportJobTest.phpclass AskuaminnvreoortAcovlrvservcelest extenos estuastorivate Logder interracexmockobnect sloggers9 usagesorivate AskJiminnvRenortActivitvService Sservice:29 GT>protected function setUpO: voidk...?11 usagesprivate function makeFilter(string Skey. ?string $value): SearchFilter&Mock0bject...hprivate function makeUser(): User&Mock0bject{...}orivate function makeSavedSearch(arnav Sfilters): Search&MockObiect..?public function testGetActivitvIdsForSavedSearchReturnsIds@: voidl...}public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(: voidt...}public function testGetActivityIdsFilters0utDateFiltersO: void{...}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandlesArrayFilters(): void{...}public function testGetActivityIdsHandlesScalarFilters(: void{...}public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaultsQ: voidAcceot$user = $this->makeUserO):SsavedSearch = sthis->makeSavedSearch(u.D:$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);sthis-›activitysearch->method( constraint: 'getArrayr1lterkeys')->w1LLReturn(LJD:ScanturedCriteria = null:sthis->activitvSearch->expects(sthis->once@)→>iecno constraind'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) (...F);$this-›elasticRepository->method( constraint: "onDemandSearchldsonly")->willReturn(LJD:sthis->loqger->method constraint: "info'D:sthis->service->getAct1v1tyldsForsavedsearch(ssavedsearch, suser):$this->assertNotNull($capturedCriteria):sthis->assertFalse(ScapturedCriteria->1sF1rstrequest0.hpublic function testGetActivitvIdsLogsWithCorrectContext@: voidf...}Accept File 8+X Reject File 1 38 @+ 2 of 2 files →Renect• Support Daily • in 2 h 53 m100% |45]Tue 14 Apr 12:07:57L AskJiminnyReportActivityServiceT..DefaultsCascade*ControlleAutomated Report Ma© Fixing Ask Jiminny Fmrequest eauisiro d ano 1sFirstreovesto reurs true when emotyseouencenunbetThe frontend URL has sequence number=4 — meaning it's not a firstreduest, Tihe service doesn't ser lt, so the criteria thinks it's a first reduest.When isFirstRequest() = true , these implicit filters are applied thataren tin the saveo search" ACLIVILVDIationRande — applies min duration = 1 (INITIAL MIN)— flters out 0-second callls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE =OPTION_RECORDED) — filters to recorded-onlyOrganiserGroupin — applies user's default group filterbut the Trontend With sequence number=4 sklos all or these deraults, so itreturns more resultsIne tix snoule be in bus lakequestraransfrombearch — it neeas to pass sequence number In the oult oarams lo sional "nota Ttistrecuest", so the.implicit detaults don't apply. Or alternatively, always pass a non-zero sequence number in tne meree in ceractivitylasrorsavecsearchNow let me verify my understanding of isfirstRequest :keae uriterla.ono ?Contirmeo, Ine Tx s cear ano minimar Une oetActivlvlosrorsavedsearich method needs to pass sequence_number with a non-zero value so that 1sFirstRequest() returns false and no implicit defaults are applied• AskJi.Now let me check il tnere's an existine lesttor AskuiminnykeportaccivicyService to uodate.Explored AskJiminnyReportActivityServiceTest.php and searched AskJi... ›Ineed to ade a lest that vertles sequence numderet is passeeto cricerlaso 1srurstreqvestlo rerurns tallse)r ler meaco Ilo tne ex sune lestfile.• AskJiminnyReportActivityServiceTest.phpNow let's run the test to verify:rtactivityservicelest.pnpphp /var/www/html/artisan testnauon nuculld ceunerot topnonocicnmynerenocoverayeCould not open input file: /var/www/html/artisandockerexec docker lamp 1 php /app/artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyRepoTenclevelyoeivecelesteune e-norcovelayeKUnX+SkipView all.sk/AutomatedReports/@ AskJiminnvReportActivitvServiceTest.phv +27.../Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php+1 -1Reject allAccept allAsk anything (&+L)+ ‹› CodeClaude Sonnet 4.6winasun leamsuir-oia 4 spaces...
|
NULL
|
-3412582121067477459
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodelaravePetactonTool PhpStormFileFditViewNavigateCodelaravePetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.phpD Unit>DActions> Component› Configuration> MConsoleM ContractsM DomainD DTO• Enums_Events_ Exceptions© AutomatedReportsCommand.phpC AutomatedReportsSendCommand.phpAddLayoutentities.php(C) Team.nho© AutomatedReportsRepository.php X© CreateHeldActivityEvent.phpC CreateActivityLoggedEvent.php(C) Activtv odded.nnrc) AutomatedRenorscalloackoelvice.onvC RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.phpAuLomaleakeportkesult.ono© AutomatedReport.php→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M Activitvclass AutomatedReportsrepos1toryA15 X4 ^> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobtcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyD User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications› M ObserversPoliciesProvidersRepositoriesD Rules• _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c AutomatedRenor* dreturn AutomatedReportpublic function create(array $data): AutomatedReport...71 M >* Find an automated report by UUID100 M ›* dparam string $uu1dAM9 MAY*dreturn AutomatedReportnul7157 A>public function findByUuid(string Suuid): ?AutomatedReport185 ₴)return AutomatedReport::where('uuid', AutomatedReport::toOptim.206 6)Tusdye225public function findbyldorUu1d(string s1d0rUu1d): ?Automatedreport227if (is_numeric($id0rUuid)) {return AutomatedReport::find((int) $id0rUuid);229236return AutomatedReport::where('uvid', AutomatedReport::to0ptim./*** Retrieve all standard (non-Ask Jaminny) automated reports.* dparam string ssortcolumnThe column to sort by. Allowed vaz 242* dparam string ssortuireccion ine sorc direccion. ALlowed values244245* drerurn cocuectonsaurondredredor»12 usagespublic function getAllStandardReports(247248string SsortColumn ="created_at',256string SsortDirection =desc): Collection 1.252 M >/*** Recrieve aLL Ask Jaminny reporus created Dy the given user.* dparam userThe user whose reports to retrieve*oodrdl sarno osorccocuminIne cocuin co sorc ou. Accowed vou* dparam string SsortDirection The sort direction. Allowed valuesWinasun ch. // View Changelog (today 10:33)E custom.loc= laravel.logL SF liminny@localhostc HS_local fiminny@localhostconcole DPOlbllL console (EU]L console (STAGINGC) AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php x C RequestGenerateAskJiminnyReportJobTest.phpclass AskuaminnvreoortAcovlrvservcelest extenos estuastorivate Logder interracexmockobnect sloggers9 usagesorivate AskJiminnvRenortActivitvService Sservice:29 GT>protected function setUpO: voidk...?11 usagesprivate function makeFilter(string Skey. ?string $value): SearchFilter&Mock0bject...hprivate function makeUser(): User&Mock0bject{...}orivate function makeSavedSearch(arnav Sfilters): Search&MockObiect..?public function testGetActivitvIdsForSavedSearchReturnsIds@: voidl...}public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(: voidt...}public function testGetActivityIdsFilters0utDateFiltersO: void{...}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandlesArrayFilters(): void{...}public function testGetActivityIdsHandlesScalarFilters(: void{...}public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaultsQ: voidAcceot$user = $this->makeUserO):SsavedSearch = sthis->makeSavedSearch(u.D:$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);sthis-›activitysearch->method( constraint: 'getArrayr1lterkeys')->w1LLReturn(LJD:ScanturedCriteria = null:sthis->activitvSearch->expects(sthis->once@)→>iecno constraind'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) (...F);$this-›elasticRepository->method( constraint: "onDemandSearchldsonly")->willReturn(LJD:sthis->loqger->method constraint: "info'D:sthis->service->getAct1v1tyldsForsavedsearch(ssavedsearch, suser):$this->assertNotNull($capturedCriteria):sthis->assertFalse(ScapturedCriteria->1sF1rstrequest0.hpublic function testGetActivitvIdsLogsWithCorrectContext@: voidf...}Accept File 8+X Reject File 1 38 @+ 2 of 2 files →Renect• Support Daily • in 2 h 53 m100% |45]Tue 14 Apr 12:07:57L AskJiminnyReportActivityServiceT..DefaultsCascade*ControlleAutomated Report Ma© Fixing Ask Jiminny Fmrequest eauisiro d ano 1sFirstreovesto reurs true when emotyseouencenunbetThe frontend URL has sequence number=4 — meaning it's not a firstreduest, Tihe service doesn't ser lt, so the criteria thinks it's a first reduest.When isFirstRequest() = true , these implicit filters are applied thataren tin the saveo search" ACLIVILVDIationRande — applies min duration = 1 (INITIAL MIN)— flters out 0-second callls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE =OPTION_RECORDED) — filters to recorded-onlyOrganiserGroupin — applies user's default group filterbut the Trontend With sequence number=4 sklos all or these deraults, so itreturns more resultsIne tix snoule be in bus lakequestraransfrombearch — it neeas to pass sequence number In the oult oarams lo sional "nota Ttistrecuest", so the.implicit detaults don't apply. Or alternatively, always pass a non-zero sequence number in tne meree in ceractivitylasrorsavecsearchNow let me verify my understanding of isfirstRequest :keae uriterla.ono ?Contirmeo, Ine Tx s cear ano minimar Une oetActivlvlosrorsavedsearich method needs to pass sequence_number with a non-zero value so that 1sFirstRequest() returns false and no implicit defaults are applied• AskJi.Now let me check il tnere's an existine lesttor AskuiminnykeportaccivicyService to uodate.Explored AskJiminnyReportActivityServiceTest.php and searched AskJi... ›Ineed to ade a lest that vertles sequence numderet is passeeto cricerlaso 1srurstreqvestlo rerurns tallse)r ler meaco Ilo tne ex sune lestfile.• AskJiminnyReportActivityServiceTest.phpNow let's run the test to verify:rtactivityservicelest.pnpphp /var/www/html/artisan testnauon nuculld ceunerot topnonocicnmynerenocoverayeCould not open input file: /var/www/html/artisandockerexec docker lamp 1 php /app/artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyRepoTenclevelyoeivecelesteune e-norcovelayeKUnX+SkipView all.sk/AutomatedReports/@ AskJiminnvReportActivitvServiceTest.phv +27.../Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php+1 -1Reject allAccept allAsk anything (&+L)+ ‹› CodeClaude Sonnet 4.6winasun leamsuir-oia 4 spaces...
|
10997
|
|
11002
|
217
|
57
|
2026-04-14T09:08:00.675611+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157680675_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v• Unit> Actions› D Component› D Configuration> MConsoleM ContractsD DomainODTO• EnumsD Events• ExceptionsO fixtures• HelpersD Http> D Integrations> Minteractions~ D Jobs> M Activitv> D AiAutomation>_ Audiov D AutomatedReports© CreateResultsTest.pl© RequestGenerateAskC RequestGenerateRerC SendReportJobTest.© SendReportMailJobTcallendar!1CrmDeaksks• MailboxD StreamingD Team• TelephonyD User© ImportRecallAlRecording© SqsVisibilityControlTestMListeners→]Mal> MModelsNotifications› M Observers[ PoliciesO ProvidersD RepositoriesC RulesServicesC Activity[ ActivityProvidersDJ AvatarcallendarConference! Cinmi[ InternalD Kioskv _ AutomatedReports© ActivityTypeServi© AskJiminnyRepori© AskJiminnyReport© AutomatedReport© ReportController.phpAutomatedReportsCommand.phpAddLayoutEntities.php© JiminnyDebugCommand.phpC AutomatedReportsSendCommand.php© Team.php© AutomatedReportsRepository.php x© CreateHeldActivityEvent.phpC CreateActivityLoggedEvent.php© ActivityLogged.phpc) AutomatedRenorscalloackoerwce.onv© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.phpAuLomaleakeportkesult.ono© AutomatedReport.phpclass AutomatedReportsRepositoryA15 X4 ^* dreturn AutomatedReportpublic function create(array $data): AutomatedReportf..}71 8 >/*** Find an automated report by UUID* @param string $uvid100 % >-1171118 ₽ >* @return AutomatedReport/nulz157 8 >public function findByUuid(string $uvid): ?AutomatedReport185 % >return AutomatedReport::where('uvid', AutomatedReport:: toOptim206 8 >225 DTusdyepublic function findBy[dOruuid(string $idoruuid): PAutomatedReport 226if (is_numeric($idOrUuid)) €return AutomatedReport::find((int) $id0rUvid);229230return AutomatedReport: :where('uvid', AutomatedReport:: toOptim/*** Retrieve all standard (non-Ask Jiminny) automated reports.* @param string $sortColumnThe column to sort by. Allowed vaz 242.* @param string $sortDirection The sort direction. Allowed values* drerurn cocuectonsaurondredredor»12 usagespublic function getAllStandardReports(string $sortColumn ='created_at',string $sortDirection = 'desc'): Collection {.247248-249250-251252 Ф >/*** Retrieve all Ask Ziminny reports created by the given user.* Oparam UserThe user whose reports to retrieve*oodrdl sarno osorccocuminIne cocuin co sorc ou. Accowed vou* dparam string SsortDirection The sort direction. Allowed valuesWinasun chз. // View Changelog (today 10:33)= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]E console (PROD]A console [EU]AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php x © RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCaseorivate Logger interracexmockobnect slodder9 usagesAl console [STAGING]42 X3 ^orVare AskunlunnvredortActultvservlce servcet29 6t >protected function setUp(): void{...}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&MockObjectf..78 usagesprivate function makeSavedSearch(array $filters): Search&MockObjectf...}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf...}public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}public function testGetActivityIdsFiltersOutDateFilters(): voidf…..}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandLesArrayFilters(): voidf...}public function testGetActivityIdsHandLesScalarFilters(): voidf...}•public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser();$savedSearch = $this->makeSavedSearch([]);$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this-›activitySearch-›method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;nanu so>acu vvsearch-sexdectsti s-sonce->necno constraind'getOnDemandPageFilterSet')->wil1ReturnCallback(function (Criteria $criteria) use ($FilterSet, &$capturedCriteria) (..3);$this->elasticRepository->method( constraint: 'onDemandSearchIdsOnly')->willReturn([I);$this->logger->method( constraint:'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequestO));public function testGetActivitvIdsLoqsWithCorrectContext@: voidf....j Support Daily • in 2h 53 mA100% C•Tue 14 Apr 12:08:00L AskJiminnyReportActivityServiceT...DefaultsCascadetControlleAutomated Report Mar© Fixing Ask Jiminny R+D ..When sequence_number is not in requestParams, the Criteria::createFromkequest ceraunsilo o, ane isrirstrequest returs true when empuy sequenceNumber === 0The frontend URL has sequence_number=4 — meaning it's not a firstrequest. Ine service doesn't serit, so the criteria thinks il's a tirst recuest.wWhen isFirstRequest() = true, these implicit filters are applied thataren tin the saved searen.1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN)- ters ouro-secono calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE =UrloN KecOrDcD — titers to recoraea-onlyOroanzsercroupin — aoolles user's ceaur orouo titerBut the frontend with sequence_number=4 skips all of these defaults, so itreturns more resuitsThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so theImol lcir cerauls con'taoov Oralernarvev alwavs oass a non-zero sequence number in the merge in getActivityIdsForSavedSearch.Now let me verify my understanding of isFirstRequest :Read Criteria.nhoConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch metnoe neeas lo oass sequence number witn a non-zero value so tnat 1sFirstRequest() returns false and no implicit defaults are applied.D AskNow let me check if there's an existing test for AskJiminnyReportActivityservice lo upaale.Explored AskJiminnyReportActivityServiceTest.php and searched AskJi...>I need to add a test that verifies sequence _number=1 is passed to Criteria(so isFirstRequest() returns false). Let me add it to the existing test• AskJiminnyReportActivityServiceTest.phpNow let's run the test to verify:ortS/ ASKJ1mInnyKeDortActivityServiceTest.phpCould not open input file: /var/www/html/artisancommana aockeldoste/ tt/ dovkces/k2o5k/ANPO/app/artisan testomatedReports/AskJiminnyReportActivityServiceTest.phpSkipItlle wiun changesvView all.../Kiosk/AutomatedReports/DAskJiminnyReportActivityService.php+1 -1Reject allAccept allAsk anything (2*L)+ <> CodeClaude Sonnet 4.6winasun leamsZ25:10Suir-o( 4 spaces...
|
NULL
|
5084243092035999080
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v• Unit> Actions› D Component› D Configuration> MConsoleM ContractsD DomainODTO• EnumsD Events• ExceptionsO fixtures• HelpersD Http> D Integrations> Minteractions~ D Jobs> M Activitv> D AiAutomation>_ Audiov D AutomatedReports© CreateResultsTest.pl© RequestGenerateAskC RequestGenerateRerC SendReportJobTest.© SendReportMailJobTcallendar!1CrmDeaksks• MailboxD StreamingD Team• TelephonyD User© ImportRecallAlRecording© SqsVisibilityControlTestMListeners→]Mal> MModelsNotifications› M Observers[ PoliciesO ProvidersD RepositoriesC RulesServicesC Activity[ ActivityProvidersDJ AvatarcallendarConference! Cinmi[ InternalD Kioskv _ AutomatedReports© ActivityTypeServi© AskJiminnyRepori© AskJiminnyReport© AutomatedReport© ReportController.phpAutomatedReportsCommand.phpAddLayoutEntities.php© JiminnyDebugCommand.phpC AutomatedReportsSendCommand.php© Team.php© AutomatedReportsRepository.php x© CreateHeldActivityEvent.phpC CreateActivityLoggedEvent.php© ActivityLogged.phpc) AutomatedRenorscalloackoerwce.onv© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.phpAuLomaleakeportkesult.ono© AutomatedReport.phpclass AutomatedReportsRepositoryA15 X4 ^* dreturn AutomatedReportpublic function create(array $data): AutomatedReportf..}71 8 >/*** Find an automated report by UUID* @param string $uvid100 % >-1171118 ₽ >* @return AutomatedReport/nulz157 8 >public function findByUuid(string $uvid): ?AutomatedReport185 % >return AutomatedReport::where('uvid', AutomatedReport:: toOptim206 8 >225 DTusdyepublic function findBy[dOruuid(string $idoruuid): PAutomatedReport 226if (is_numeric($idOrUuid)) €return AutomatedReport::find((int) $id0rUvid);229230return AutomatedReport: :where('uvid', AutomatedReport:: toOptim/*** Retrieve all standard (non-Ask Jiminny) automated reports.* @param string $sortColumnThe column to sort by. Allowed vaz 242.* @param string $sortDirection The sort direction. Allowed values* drerurn cocuectonsaurondredredor»12 usagespublic function getAllStandardReports(string $sortColumn ='created_at',string $sortDirection = 'desc'): Collection {.247248-249250-251252 Ф >/*** Retrieve all Ask Ziminny reports created by the given user.* Oparam UserThe user whose reports to retrieve*oodrdl sarno osorccocuminIne cocuin co sorc ou. Accowed vou* dparam string SsortDirection The sort direction. Allowed valuesWinasun chз. // View Changelog (today 10:33)= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]E console (PROD]A console [EU]AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php x © RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCaseorivate Logger interracexmockobnect slodder9 usagesAl console [STAGING]42 X3 ^orVare AskunlunnvredortActultvservlce servcet29 6t >protected function setUp(): void{...}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&MockObjectf..78 usagesprivate function makeSavedSearch(array $filters): Search&MockObjectf...}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf...}public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}public function testGetActivityIdsFiltersOutDateFilters(): voidf…..}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandLesArrayFilters(): voidf...}public function testGetActivityIdsHandLesScalarFilters(): voidf...}•public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser();$savedSearch = $this->makeSavedSearch([]);$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this-›activitySearch-›method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;nanu so>acu vvsearch-sexdectsti s-sonce->necno constraind'getOnDemandPageFilterSet')->wil1ReturnCallback(function (Criteria $criteria) use ($FilterSet, &$capturedCriteria) (..3);$this->elasticRepository->method( constraint: 'onDemandSearchIdsOnly')->willReturn([I);$this->logger->method( constraint:'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequestO));public function testGetActivitvIdsLoqsWithCorrectContext@: voidf....j Support Daily • in 2h 53 mA100% C•Tue 14 Apr 12:08:00L AskJiminnyReportActivityServiceT...DefaultsCascadetControlleAutomated Report Mar© Fixing Ask Jiminny R+D ..When sequence_number is not in requestParams, the Criteria::createFromkequest ceraunsilo o, ane isrirstrequest returs true when empuy sequenceNumber === 0The frontend URL has sequence_number=4 — meaning it's not a firstrequest. Ine service doesn't serit, so the criteria thinks il's a tirst recuest.wWhen isFirstRequest() = true, these implicit filters are applied thataren tin the saved searen.1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN)- ters ouro-secono calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE =UrloN KecOrDcD — titers to recoraea-onlyOroanzsercroupin — aoolles user's ceaur orouo titerBut the frontend with sequence_number=4 skips all of these defaults, so itreturns more resuitsThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so theImol lcir cerauls con'taoov Oralernarvev alwavs oass a non-zero sequence number in the merge in getActivityIdsForSavedSearch.Now let me verify my understanding of isFirstRequest :Read Criteria.nhoConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch metnoe neeas lo oass sequence number witn a non-zero value so tnat 1sFirstRequest() returns false and no implicit defaults are applied.D AskNow let me check if there's an existing test for AskJiminnyReportActivityservice lo upaale.Explored AskJiminnyReportActivityServiceTest.php and searched AskJi...>I need to add a test that verifies sequence _number=1 is passed to Criteria(so isFirstRequest() returns false). Let me add it to the existing test• AskJiminnyReportActivityServiceTest.phpNow let's run the test to verify:ortS/ ASKJ1mInnyKeDortActivityServiceTest.phpCould not open input file: /var/www/html/artisancommana aockeldoste/ tt/ dovkces/k2o5k/ANPO/app/artisan testomatedReports/AskJiminnyReportActivityServiceTest.phpSkipItlle wiun changesvView all.../Kiosk/AutomatedReports/DAskJiminnyReportActivityService.php+1 -1Reject allAccept allAsk anything (2*L)+ <> CodeClaude Sonnet 4.6winasun leamsZ25:10Suir-o( 4 spaces...
|
11000
|
|
11003
|
217
|
58
|
2026-04-14T09:08:03.619798+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157683619_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v• Unit> Actions› D Component› D Configuration> MConsoleM ContractsD DomainDDTO• EnumsD Events• ExceptionsO fixtures• HelpersD Http> D Integrations> Minteractions~ D Jobs> M Activitv> D AiAutomation>_ Audiov D AutomatedReports© CreateResultsTest.pl© RequestGenerateAskC RequestGenerateRerC SendReportJobTest.© SendReportMailJobTcallendar!1CrmDeak sks• MailboxD StreamingD Team• TelephonyD User© ImportRecallAlRecording© SqsVisibilityControlTestMListeners→]Mal> MModelsNotifications› M Observers[ PoliciesO ProvidersD RepositoriesC RulesServicesC Activity[ ActivityProvidersDJ AvatarcallendarConference! Cinmi[ InternalD Kioskv _ AutomatedReports© ActivityTypeServi© AskJiminnyRepori© AskJiminnyReport© AutomatedReport© ReportController.phpAutomatedReportsCommand.phpAddLayoutEntities.php© JiminnyDebugCommand.phpC AutomatedReportsSendCommand.php© Team.php© AutomatedReportsRepository.php x© CreateHeldActivityEvent.phpC CreateActivityLoggedEvent.php© ActivityLogged.phpc) AutomatedRenorscalloackoelvice.onv© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.phpAuLomaleakeportkesult.ono© AutomatedReport.phpclass AutomatedReportsRepositoryA15 X4 ^* dreturn AutomatedReportpublic function create(array $data): AutomatedReportf..}71 8 >/*** Find an automated report by UUID* @param string $uvid100 % >-1171118 ₽ >* @return AutomatedReport/null157 8 >public function findByUuid(string $uvid): ?AutomatedReport185 % >return AutomatedReport::where('uvid', AutomatedReport:: toOptim206 8 >225 DTusdyepublic function findBy[dOruuid(string $idoruuid): PAutomatedReport 226if (is_numeric($idOrUuid)) €return AutomatedReport::find((int) $id0rUvid);228229230return AutomatedReport: :where('uvid', AutomatedReport:: toOptim/*** Retrieve all standard (non-Ask Jiminny) automated reports.* @param string $sortColumnThe column to sort by. Allowed vaz 242* @param string $sortDirection The sort direction. Allowed values* drerurn cocuectonsaurondredredor»12 usagespublic function getAllStandardReports(string $sortColumn ='created_at',string $sortDirection = 'desc'): Collection {.247248-249250-251252 Ф >/*** Retrieve all Ask Ziminny reports created by the given user.* Oparam UserThe user whose reports to retrieve*oodrdl sarno osorccocuminIne cocuin co sorc ou. Accowed vou* dparam string SsortDirection The sort direction. Allowed valuesWinasur chз. // View Changelog (today 10:33)= custom.logE laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]Al console [PROD]A console [EU]AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php x © RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivate LoggerIntertace&Mock0bject $logger;9 usagesAl console [STAGING]j Support Daily • in 2h 52mAL AskJiminnyReportActivityServiceT...DefaultsCascadetControlleAutomated Report Mar100% C•Tue 14 Apr 12:08:03O Fixing Ask Jiminny R+D ..42 X3 ^orVare AskunlunnvredortActultvservlce servcet29 6t >protected function setUp(): void{...}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&MockObjectf..78 usagesprivate function makeSavedSearch(array $filters): Search&MockObjectf...}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf...}public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}public function testGetActivityIdsFiltersOutDateFilters(): voidf...}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandLesArrayFilters(): voidf...}public function testGetActivityIdsHandLesScalarFilters(): voidf...}•public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser();$savedSearch = $this->makeSavedSearch([]);$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this-›activitySearch-›method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;nanu so>acu vvsearch-sexdectsti s-sonce->neuno constraint'getOnDemandPageFilterSet')->wil1ReturnCallback(function (Criteria $criteria) use ($FilterSet, &$capturedCriteria) (..3);$this->elasticRepository->method( constraint: 'onDemandSearchIdsOnly')->willReturn([I);$this->logger->method( constraint:'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequestO));public function testGetActivitvIdsLoqsWithCorrectContext@: voidf....mkequest deraunsiuto o ane isrirsthequesel returs true when empyvsequenceumber ===The frontend URL has sequence_number=4 - meaning it's not a firstreouest. Ine service doesn't setlt, so te crlterla tninks il's a tirst reouest.When uspurstRequest = true.nese mollcttitersareadole. tnararen't in the saved search.1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN)- Tlters out o-secone calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE =OPTION_RECORDED) - filters to recorded-only3. OrganiserGroupIn - applies user's default group filterBut the frontend with sequence_number=4 skips all of these defaults, so itreturs more resuitsThe fix should be in bui ldrequestParamsFromsearch - it needs to pass sequence_number in the built params to signal "not a first request", so theImplicit deraults dont apoly. or alternatively, always pass a non-zero sequence number In the meroe in detactivitviidsForsaverSearch.Read AskJiminnyReportActivityService.php #L44-93Now let me verify my understanchtg of isFirstRequest:Read criteria.nnoConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch metnoe neeas to pass sequence number with a non-zero value so that 1srurstrequestl rerurns false anc nomolcrcecursarea..leo• AskJiminnyReportActivityService.php+1 -1Now let me check if there's an existing test for AskJiminnyReportActivityservice to updale.Explored AskJiminnvReoortActivtvServicelest.onv and searched Ask.h.I need to add a test that verifies sequence_number=1 is passed to Criteria(so isFirstRequest() returns false). Let me add it to the existing test• AskJiminnyReportActivityServiceTest.phpNow let's run the test to verify:rtActivityServiceTest.phpCould not open input file: /var/www/html/artisanartisanieportes AskJiminnyRepoCould not open input file: /app/artisanItlle wiun changesvView all.../Kiosk/AutomatedReports/DAskJiminnyReportActivityService.php+1 -1Reject allAccept allAsk anything (20L)+ <> CodeClaude Sonnet 4.6225:103uir-o( 4 spaces...
|
NULL
|
3803632695952396004
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject v• Unit> Actions› D Component› D Configuration> MConsoleM ContractsD DomainDDTO• EnumsD Events• ExceptionsO fixtures• HelpersD Http> D Integrations> Minteractions~ D Jobs> M Activitv> D AiAutomation>_ Audiov D AutomatedReports© CreateResultsTest.pl© RequestGenerateAskC RequestGenerateRerC SendReportJobTest.© SendReportMailJobTcallendar!1CrmDeak sks• MailboxD StreamingD Team• TelephonyD User© ImportRecallAlRecording© SqsVisibilityControlTestMListeners→]Mal> MModelsNotifications› M Observers[ PoliciesO ProvidersD RepositoriesC RulesServicesC Activity[ ActivityProvidersDJ AvatarcallendarConference! Cinmi[ InternalD Kioskv _ AutomatedReports© ActivityTypeServi© AskJiminnyRepori© AskJiminnyReport© AutomatedReport© ReportController.phpAutomatedReportsCommand.phpAddLayoutEntities.php© JiminnyDebugCommand.phpC AutomatedReportsSendCommand.php© Team.php© AutomatedReportsRepository.php x© CreateHeldActivityEvent.phpC CreateActivityLoggedEvent.php© ActivityLogged.phpc) AutomatedRenorscalloackoelvice.onv© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.phpAuLomaleakeportkesult.ono© AutomatedReport.phpclass AutomatedReportsRepositoryA15 X4 ^* dreturn AutomatedReportpublic function create(array $data): AutomatedReportf..}71 8 >/*** Find an automated report by UUID* @param string $uvid100 % >-1171118 ₽ >* @return AutomatedReport/null157 8 >public function findByUuid(string $uvid): ?AutomatedReport185 % >return AutomatedReport::where('uvid', AutomatedReport:: toOptim206 8 >225 DTusdyepublic function findBy[dOruuid(string $idoruuid): PAutomatedReport 226if (is_numeric($idOrUuid)) €return AutomatedReport::find((int) $id0rUvid);228229230return AutomatedReport: :where('uvid', AutomatedReport:: toOptim/*** Retrieve all standard (non-Ask Jiminny) automated reports.* @param string $sortColumnThe column to sort by. Allowed vaz 242* @param string $sortDirection The sort direction. Allowed values* drerurn cocuectonsaurondredredor»12 usagespublic function getAllStandardReports(string $sortColumn ='created_at',string $sortDirection = 'desc'): Collection {.247248-249250-251252 Ф >/*** Retrieve all Ask Ziminny reports created by the given user.* Oparam UserThe user whose reports to retrieve*oodrdl sarno osorccocuminIne cocuin co sorc ou. Accowed vou* dparam string SsortDirection The sort direction. Allowed valuesWinasur chз. // View Changelog (today 10:33)= custom.logE laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]Al console [PROD]A console [EU]AskJiminnyReportActivityService.php© AskJiminnyReportActivityServiceTest.php x © RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivate LoggerIntertace&Mock0bject $logger;9 usagesAl console [STAGING]j Support Daily • in 2h 52mAL AskJiminnyReportActivityServiceT...DefaultsCascadetControlleAutomated Report Mar100% C•Tue 14 Apr 12:08:03O Fixing Ask Jiminny R+D ..42 X3 ^orVare AskunlunnvredortActultvservlce servcet29 6t >protected function setUp(): void{...}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&MockObjectf..78 usagesprivate function makeSavedSearch(array $filters): Search&MockObjectf...}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf...}public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}public function testGetActivityIdsFiltersOutDateFilters(): voidf...}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandLesArrayFilters(): voidf...}public function testGetActivityIdsHandLesScalarFilters(): voidf...}•public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser();$savedSearch = $this->makeSavedSearch([]);$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this-›activitySearch-›method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;nanu so>acu vvsearch-sexdectsti s-sonce->neuno constraint'getOnDemandPageFilterSet')->wil1ReturnCallback(function (Criteria $criteria) use ($FilterSet, &$capturedCriteria) (..3);$this->elasticRepository->method( constraint: 'onDemandSearchIdsOnly')->willReturn([I);$this->logger->method( constraint:'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequestO));public function testGetActivitvIdsLoqsWithCorrectContext@: voidf....mkequest deraunsiuto o ane isrirsthequesel returs true when empyvsequenceumber ===The frontend URL has sequence_number=4 - meaning it's not a firstreouest. Ine service doesn't setlt, so te crlterla tninks il's a tirst reouest.When uspurstRequest = true.nese mollcttitersareadole. tnararen't in the saved search.1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN)- Tlters out o-secone calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE =OPTION_RECORDED) - filters to recorded-only3. OrganiserGroupIn - applies user's default group filterBut the frontend with sequence_number=4 skips all of these defaults, so itreturs more resuitsThe fix should be in bui ldrequestParamsFromsearch - it needs to pass sequence_number in the built params to signal "not a first request", so theImplicit deraults dont apoly. or alternatively, always pass a non-zero sequence number In the meroe in detactivitviidsForsaverSearch.Read AskJiminnyReportActivityService.php #L44-93Now let me verify my understanchtg of isFirstRequest:Read criteria.nnoConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch metnoe neeas to pass sequence number with a non-zero value so that 1srurstrequestl rerurns false anc nomolcrcecursarea..leo• AskJiminnyReportActivityService.php+1 -1Now let me check if there's an existing test for AskJiminnyReportActivityservice to updale.Explored AskJiminnvReoortActivtvServicelest.onv and searched Ask.h.I need to add a test that verifies sequence_number=1 is passed to Criteria(so isFirstRequest() returns false). Let me add it to the existing test• AskJiminnyReportActivityServiceTest.phpNow let's run the test to verify:rtActivityServiceTest.phpCould not open input file: /var/www/html/artisanartisanieportes AskJiminnyRepoCould not open input file: /app/artisanItlle wiun changesvView all.../Kiosk/AutomatedReports/DAskJiminnyReportActivityService.php+1 -1Reject allAccept allAsk anything (20L)+ <> CodeClaude Sonnet 4.6225:103uir-o( 4 spaces...
|
NULL
|
|
11005
|
217
|
59
|
2026-04-14T09:08:06.651449+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157686651_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactonToo PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.php= custom.log= laravel.l0gL SF (iminny@localhostL HS_local fiminny@localhost)& console (PROD]D Unit>DActions> ComponentConfigurationM ConsoleM ContractsM DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ Helpers•_ Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners© AutomatedReportsCommand.php4 console [EUl4 console [STAGING]© AskJiminnyReportActivityService.php© AutomatedReportsSendCommand.phpC AddLayoutEntities.phpC AskJiminnyReportActivityServiceTest.php *© RequestGenerateAskJiminnyReportJobTest.phpC) Team.onp(©) AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseviavale Loucerencer тaceхmockud cel sroceeln9 usagesA2/3 MV© TrackProviderInstalledEvent.phpc) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php29 @ >(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:> MModelsM Notifications› M ObserversPoliciesProviders→ Repositories> D Rulesv _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServiC Ack.imnnyRepor(c) AskJiminnyRepor(c) AutomatedRenonA15 M4 . V* dreturn Automatedreportpublic function create(array $data): Automate* rino on qucondred revorr ou vuru* @param string Suuid* dreturn AutomatedReport nullpublic function findbyuuld(string suuld): ?Al2asreturn AutomatedReport::where 'uu1d', AUt2oz157 % >184185 M >DA6VA— 2251 usagepubLic tunction tindby.auruunalscring +1aurut 228ifis numeric($id0rUuidreturn AutomatedReport:: find((int) $1231233return Automatedkeport: :where('uuld", AUt 234235236237* Recrieve alc scandara (non-Ask Jimanny) al24212451*oodrdl sarno osorccocuminThe column cC244* @param string $sortDirection The sort dire 245246* dreturn Collection<AutomatedReport>247_24812 usages249public function getAllStandardReports250string Ssortcolumn ='created_at'251scring ssortbireccion = "desc": Collection {...252 V—214* Retrieve all Ask Jiminny reports created tprivate ASkJ1minnyReportAct1v1tyService sservice:protected function setUp(): void{...}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject(...}ousadesprivate function makeUser@: User&Mock0biect(...8 usagesprivate function makeSavedSearch(array sfilters): Search&Mock0bject...public function testGetActivityldsForsavedsearchReturnsids: vo1di...лpublic function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void{...}public function testGetActivityIdsFilters0utDateFilters(: voidf...}public function testGetActivitvIdsFilters0utClosingPeriodDateFiltersO: voidf...?public function testGetActivityIdsHandLesArrayFilters(): void{...}public function testGetActivityIdsHandlesScalarFilters(): void{...}public function testGetActiv1tyldsPassesNonZeroSequenceNumberlob1sabler1rstrequestbefauuts(nuser z sus-snakeuserussavedsearch = schls->makesavedsearcnul.:$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);sthis-›activitySearch->method( constraint: 'qetArrayFilterKeys')->willReturn(00:ScapturedCriteria = null;sthis->activ1tysearch->expects(sth1s->once)->method( constraint: 'getonDemandPageFilterset')->WILLReturnCallback(function (Criteria scriteria) use (sfilterset, xcapturedcritSthis-›elasticRepository->method( constraint: 'onDemandSearchIdsOnlv')->willReturn([1):$this->logger->method( constraint:'info');фchus->service->gecaccivicyrasroroavedsearchtesavedsearch, puser):sthis->assertNotNullScapturedCriteria):sthis-›assertFalseScapturedCriteria->isFirstRequest00:public function testGetActivityldsLogsW1thcorrectcontext: vo1di...hWinasur change: Support Daily • in 2h 52 m100% |45]Tue 14 Apr 12:08:06L AskJiminnyReportActivityServiceT….DefaultscaccadeFixing ReportControlleiAutomated Renort MaiFixing Ask Jiminny P+0 .Now nave the key insienu Let me check what sequence nunder coes in tne context or isrirstrequest.Searched isFirstRequest in app/Component/ActivitySearch (*.php) (/)This is the root cause. Let me check ActivityActualDate in detall:Read ActivityActualDate.phNow I see the full picture. Let me also check ActivityDurationRange and ActivityRecorded detaults for isFirstRequest() :Read ActivitvDuration?Now l have the complete root cause picture. This is critical:Root Cause FoundThe buildRequestParamsFromSearch method in AskJiminnyReportActivityService passes sequence number=0 implicitly (not in params), which meansisFirstRequest() returns true.When sequence_number is notin requestParams, the Criteria:: createFromRequest detaultsitto 0, and isFirstRequest() returns true when empty llsequenceNumber == 0.The frontend URL has sequence number=4 — meanina it's not a first request. The service doesn't set it. so the criteria thinks it's a first requestWhen isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) — filters to recorded-onlyorgannsergroupin — aoolesuser's ceaur orouo titerBut the frontend with sequence number=4 skips all of these defaults, so it returns more resultsThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence_number in the merge in getActivityldsForSavedSearch.Read AskJiminnyReportActivityService.php #L44-93Now let me verify my understanding of isFirstRequest :Read criteria.onoConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch method needs to pass sequence number with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.ASkuIminnvreoonAcuvuservce.onoNow let me check if there's an existing test for AskJiminnyReportActivityService to update:Exolored Ask.liminnvReIneed to add a test that verifies sequence number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:• AskJiminnyReportActivityServiceTest.phpNow let's run the test to verifyCommand dockeldorker eyer docker lamn 1 nho var ww htmibartican tecttests/unttervices/Klosk/Automatedkenorts/ask.nminnvkenortactiv1tv.ervicellest.oho =-no-coveradeCould not open input file: /var/www/html/artisanCommand docken• docker exerc docker_lantests/Unit/Services/Kjate/aeports/AskJiminnyReportActivityserviceTest.php --no-coverageCould not open input file: /app/artisanhloauinaVew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (&+L)+ <> Code Claude Sonnet 4.6winasun leamsZ25:10Suir-oia 4 spacesew...
|
NULL
|
5338531742167179584
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactonToo PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.php= custom.log= laravel.l0gL SF (iminny@localhostL HS_local fiminny@localhost)& console (PROD]D Unit>DActions> ComponentConfigurationM ConsoleM ContractsM DomainD DTO• Enums_ Events_ Exceptions→ fixtures_ Helpers•_ Http>_Integrations> Minteractions• D Jobs> M Activitv> M AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners© AutomatedReportsCommand.php4 console [EUl4 console [STAGING]© AskJiminnyReportActivityService.php© AutomatedReportsSendCommand.phpC AddLayoutEntities.phpC AskJiminnyReportActivityServiceTest.php *© RequestGenerateAskJiminnyReportJobTest.phpC) Team.onp(©) AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseviavale Loucerencer тaceхmockud cel sroceeln9 usagesA2/3 MV© TrackProviderInstalledEvent.phpc) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php29 @ >(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:> MModelsM Notifications› M ObserversPoliciesProviders→ Repositories> D Rulesv _ Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServiC Ack.imnnyRepor(c) AskJiminnyRepor(c) AutomatedRenonA15 M4 . V* dreturn Automatedreportpublic function create(array $data): Automate* rino on qucondred revorr ou vuru* @param string Suuid* dreturn AutomatedReport nullpublic function findbyuuld(string suuld): ?Al2asreturn AutomatedReport::where 'uu1d', AUt2oz157 % >184185 M >DA6VA— 2251 usagepubLic tunction tindby.auruunalscring +1aurut 228ifis numeric($id0rUuidreturn AutomatedReport:: find((int) $1231233return Automatedkeport: :where('uuld", AUt 234235236237* Recrieve alc scandara (non-Ask Jimanny) al24212451*oodrdl sarno osorccocuminThe column cC244* @param string $sortDirection The sort dire 245246* dreturn Collection<AutomatedReport>247_24812 usages249public function getAllStandardReports250string Ssortcolumn ='created_at'251scring ssortbireccion = "desc": Collection {...252 V—214* Retrieve all Ask Jiminny reports created tprivate ASkJ1minnyReportAct1v1tyService sservice:protected function setUp(): void{...}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject(...}ousadesprivate function makeUser@: User&Mock0biect(...8 usagesprivate function makeSavedSearch(array sfilters): Search&Mock0bject...public function testGetActivityldsForsavedsearchReturnsids: vo1di...лpublic function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void{...}public function testGetActivityIdsFilters0utDateFilters(: voidf...}public function testGetActivitvIdsFilters0utClosingPeriodDateFiltersO: voidf...?public function testGetActivityIdsHandLesArrayFilters(): void{...}public function testGetActivityIdsHandlesScalarFilters(): void{...}public function testGetActiv1tyldsPassesNonZeroSequenceNumberlob1sabler1rstrequestbefauuts(nuser z sus-snakeuserussavedsearch = schls->makesavedsearcnul.:$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);sthis-›activitySearch->method( constraint: 'qetArrayFilterKeys')->willReturn(00:ScapturedCriteria = null;sthis->activ1tysearch->expects(sth1s->once)->method( constraint: 'getonDemandPageFilterset')->WILLReturnCallback(function (Criteria scriteria) use (sfilterset, xcapturedcritSthis-›elasticRepository->method( constraint: 'onDemandSearchIdsOnlv')->willReturn([1):$this->logger->method( constraint:'info');фchus->service->gecaccivicyrasroroavedsearchtesavedsearch, puser):sthis->assertNotNullScapturedCriteria):sthis-›assertFalseScapturedCriteria->isFirstRequest00:public function testGetActivityldsLogsW1thcorrectcontext: vo1di...hWinasur change: Support Daily • in 2h 52 m100% |45]Tue 14 Apr 12:08:06L AskJiminnyReportActivityServiceT….DefaultscaccadeFixing ReportControlleiAutomated Renort MaiFixing Ask Jiminny P+0 .Now nave the key insienu Let me check what sequence nunder coes in tne context or isrirstrequest.Searched isFirstRequest in app/Component/ActivitySearch (*.php) (/)This is the root cause. Let me check ActivityActualDate in detall:Read ActivityActualDate.phNow I see the full picture. Let me also check ActivityDurationRange and ActivityRecorded detaults for isFirstRequest() :Read ActivitvDuration?Now l have the complete root cause picture. This is critical:Root Cause FoundThe buildRequestParamsFromSearch method in AskJiminnyReportActivityService passes sequence number=0 implicitly (not in params), which meansisFirstRequest() returns true.When sequence_number is notin requestParams, the Criteria:: createFromRequest detaultsitto 0, and isFirstRequest() returns true when empty llsequenceNumber == 0.The frontend URL has sequence number=4 — meanina it's not a first request. The service doesn't set it. so the criteria thinks it's a first requestWhen isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) — filters to recorded-onlyorgannsergroupin — aoolesuser's ceaur orouo titerBut the frontend with sequence number=4 skips all of these defaults, so it returns more resultsThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence_number in the merge in getActivityldsForSavedSearch.Read AskJiminnyReportActivityService.php #L44-93Now let me verify my understanding of isFirstRequest :Read criteria.onoConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch method needs to pass sequence number with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.ASkuIminnvreoonAcuvuservce.onoNow let me check if there's an existing test for AskJiminnyReportActivityService to update:Exolored Ask.liminnvReIneed to add a test that verifies sequence number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:• AskJiminnyReportActivityServiceTest.phpNow let's run the test to verifyCommand dockeldorker eyer docker lamn 1 nho var ww htmibartican tecttests/unttervices/Klosk/Automatedkenorts/ask.nminnvkenortactiv1tv.ervicellest.oho =-no-coveradeCould not open input file: /var/www/html/artisanCommand docken• docker exerc docker_lantests/Unit/Services/Kjate/aeports/AskJiminnyReportActivityserviceTest.php --no-coverageCould not open input file: /app/artisanhloauinaVew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (&+L)+ <> Code Claude Sonnet 4.6winasun leamsZ25:10Suir-oia 4 spacesew...
|
11003
|
|
11008
|
217
|
61
|
2026-04-14T09:08:15.913338+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157695913_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.s vProject vEditViewNavigate PhpStormFileFV faVsco.s vProject vEditViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]• Unit> Actions› D ComponentConfigurationO ConsoleM ContractsM DomainDDTO• EnumsD Events• ExceptionsO fixtures• Helpers©Http> D Integrations> MinteractionsMJobs> M Activitv> D AiAutomation> D Audiov D AutomatedReports© CreateResultsTest.pl© RequestGenerateAskC RequestGenerateRerC SendReportJobTest.© SendReportMailJobTcallendar!1CrmDeaksks• MailboxD StreamingD Team• TelephonyD User© ImportRecallAlRecording© SqsVisibilityControlTest> D Listeners→]Mal> MModelsNotifications› M ObserversOPolicies› Providers> DJ Repositories> D Rules~ D Services[ Activity[ ActivityProvidersD AvatarD CalendarConference! Cinmi[ InternalD Kioskv _ AutomatedReports© ActivityTypeServiC Ack.iminyReport© AskJiminnyReport© AutomatedReport< console EUiconsole SlAGiNGAskJiminnykeporlAcuivilyservice.ong x© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceActivityUpdatedDate::PARAM_UPDATED_FROM,ActivityUpdatedDate: :PARAM_UPDATED_TO,© TrackProviderInstalledEvent.phpClosingPeriodFilter::KEY_START_DATE,© CreateActivityLoggedEvent.php© UserPilotActivityListener.phpClosingPeriodFilter::KEY_END_DATE,(©) ActivityLogged.php];AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V.4 ^1 usagepublic function __construct(private readonly ActivitvSearch SactivitvSearch.privace readonty clasticacciуiсукерosсогy фelаsсскерosiсory.private readonly LoggerInterface $logger,D4...3* Oreturn AutomatedReportpublic function create(array $data): Automate/*** Find an automated report by UUID* @param string $uvid* Oreturn AutomatedReport|null46public function findByUuid(string $uvid): ?ALreturn AutomatedReport: :where('uvid', Aut1 usagepublic function findById0rUuid(string $id0rtt 51if (is_numeric($id0rUuid)) {53return AutomatedReport:: find((int) $154return AutomatedReport: :Where('uvid', Aut57/*** Retrieve all standard (non-Ask Liminny) al 61* oodral sarno osorccocunnThe column t( 63* @param string $sortDirection The sort dire64* Oreturn Collection<AutomatedReport>66_6712 usagespublic function getAllStandardReports(string $sortColumn ='created_at',string $sortDirection = 'desc'): Collection f.+/*** Retrieve all Ask Liminny reports created k74* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behavioun of getContextForAskAnythingByFilte* Creturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array &$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequestCAcceptmargee €$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskJiminnyReport] Fetched activity IDs for saved search', ['saveo search 10'> $savedSearch->getId(),'user_id' => Suser-›getId@,'activity_count' => count($activityIds),1):return $activityIds;1 usageprivate function buildRequestParamsFromSearch(Search $savedSearch,User $user): array$params = [];nanravnurerkeys = nus-racau toearci-poerArravrturerkeys userrforeach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPronertvO:$value = $Filter->getFhlt.X Reject File 0* €Winasur changeSupport Daily • in 2h 52mAL AskJiminnyReportActivityServiceT...Defaults100% |45]Tue 14 Apr 12:08:15CascadeFixing ReportControllerAutomated Report Mar• Fixing Ask Jiminny RNow nave the key insienu Let me check what sequence nunder coes in tne context or isrirstrequest.+D ...eSearched isFirstRequest in app/Component/ActivitySearch (-php) (7)This is the root cause. Let me check ActivityActualDate in detail:Read ActivNow I see the full picture. Let me also check ActivityDurationRange and ActivityRecorded defaults for isFirstRequest() :Read ActivitvDuration?Now I have the complete root cause picture. This is critical:wRoot Cause FoundThe rs eResti) elinas tr8eaFromSearch method in AskJiminnyReportActivityService passes sequence_number=0 implicitly (not in params), which meansWhen sequence_number is not in requestParams, the Criteria:: createFromRequest defaults it to 0, and isFirstRequest() returns true when empty 11sequenceNumber == 0.The frontend URL has sequence number=4 — meanina it's not a first request. The service doesn't set it. so the criteria thinks it's a first reguestWhen isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-onlyorgannsergroupin — aoolesuser's ceaur orouo titerBut the frontend with sequence_number=4 skips all of these defaults, so it returns more results.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence_number in the merge in getActivityldsForSavedSearch.Read AskJiminnyReportActivityService.php #L44-93Now let me verify my understanding of isFirstRequest :Read criteria.onoConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch method needs to pass sequence_number with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.ASkJIminnvreoorAc.Vivservice.onoNow let me check T there's an existine lesttor AskJiminnykeportaccivicyservice lo uodale:Exolored Ask.liminnvReI need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:AskJiminnyReportActivityServiceTest.phpNow let's run the test to verify:Command dockeldocker exec docker lamp 1 php /var/www/html/artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverageCould not open input file: /var/www/html/artisanCommand dockerodoste/une/ervaces/KJosk/AuF omaate/aeports/AskJiminnyReportActivityserviceTest.php --no-coverageCould not open input file: /app/artisannavicaunohVew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> CodeClaude Sonnet 4.6winasun leamsb8: /ob chars, 23 line breaksuir-o( 4 spaces...
|
NULL
|
5324824059177070058
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFV faVsco.s vProject vEditViewNavigate PhpStormFileFV faVsco.s vProject vEditViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]• Unit> Actions› D ComponentConfigurationO ConsoleM ContractsM DomainDDTO• EnumsD Events• ExceptionsO fixtures• Helpers©Http> D Integrations> MinteractionsMJobs> M Activitv> D AiAutomation> D Audiov D AutomatedReports© CreateResultsTest.pl© RequestGenerateAskC RequestGenerateRerC SendReportJobTest.© SendReportMailJobTcallendar!1CrmDeaksks• MailboxD StreamingD Team• TelephonyD User© ImportRecallAlRecording© SqsVisibilityControlTest> D Listeners→]Mal> MModelsNotifications› M ObserversOPolicies› Providers> DJ Repositories> D Rules~ D Services[ Activity[ ActivityProvidersD AvatarD CalendarConference! Cinmi[ InternalD Kioskv _ AutomatedReports© ActivityTypeServiC Ack.iminyReport© AskJiminnyReport© AutomatedReport< console EUiconsole SlAGiNGAskJiminnykeporlAcuivilyservice.ong x© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceActivityUpdatedDate::PARAM_UPDATED_FROM,ActivityUpdatedDate: :PARAM_UPDATED_TO,© TrackProviderInstalledEvent.phpClosingPeriodFilter::KEY_START_DATE,© CreateActivityLoggedEvent.php© UserPilotActivityListener.phpClosingPeriodFilter::KEY_END_DATE,(©) ActivityLogged.php];AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V.4 ^1 usagepublic function __construct(private readonly ActivitvSearch SactivitvSearch.privace readonty clasticacciуiсукерosсогy фelаsсскерosiсory.private readonly LoggerInterface $logger,D4...3* Oreturn AutomatedReportpublic function create(array $data): Automate/*** Find an automated report by UUID* @param string $uvid* Oreturn AutomatedReport|null46public function findByUuid(string $uvid): ?ALreturn AutomatedReport: :where('uvid', Aut1 usagepublic function findById0rUuid(string $id0rtt 51if (is_numeric($id0rUuid)) {53return AutomatedReport:: find((int) $154return AutomatedReport: :Where('uvid', Aut57/*** Retrieve all standard (non-Ask Liminny) al 61* oodral sarno osorccocunnThe column t( 63* @param string $sortDirection The sort dire64* Oreturn Collection<AutomatedReport>66_6712 usagespublic function getAllStandardReports(string $sortColumn ='created_at',string $sortDirection = 'desc'): Collection f.+/*** Retrieve all Ask Liminny reports created k74* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behavioun of getContextForAskAnythingByFilte* Creturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array &$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequestCAcceptmargee €$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskJiminnyReport] Fetched activity IDs for saved search', ['saveo search 10'> $savedSearch->getId(),'user_id' => Suser-›getId@,'activity_count' => count($activityIds),1):return $activityIds;1 usageprivate function buildRequestParamsFromSearch(Search $savedSearch,User $user): array$params = [];nanravnurerkeys = nus-racau toearci-poerArravrturerkeys userrforeach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPronertvO:$value = $Filter->getFhlt.X Reject File 0* €Winasur changeSupport Daily • in 2h 52mAL AskJiminnyReportActivityServiceT...Defaults100% |45]Tue 14 Apr 12:08:15CascadeFixing ReportControllerAutomated Report Mar• Fixing Ask Jiminny RNow nave the key insienu Let me check what sequence nunder coes in tne context or isrirstrequest.+D ...eSearched isFirstRequest in app/Component/ActivitySearch (-php) (7)This is the root cause. Let me check ActivityActualDate in detail:Read ActivNow I see the full picture. Let me also check ActivityDurationRange and ActivityRecorded defaults for isFirstRequest() :Read ActivitvDuration?Now I have the complete root cause picture. This is critical:wRoot Cause FoundThe rs eResti) elinas tr8eaFromSearch method in AskJiminnyReportActivityService passes sequence_number=0 implicitly (not in params), which meansWhen sequence_number is not in requestParams, the Criteria:: createFromRequest defaults it to 0, and isFirstRequest() returns true when empty 11sequenceNumber == 0.The frontend URL has sequence number=4 — meanina it's not a first request. The service doesn't set it. so the criteria thinks it's a first reguestWhen isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-onlyorgannsergroupin — aoolesuser's ceaur orouo titerBut the frontend with sequence_number=4 skips all of these defaults, so it returns more results.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence_number in the merge in getActivityldsForSavedSearch.Read AskJiminnyReportActivityService.php #L44-93Now let me verify my understanding of isFirstRequest :Read criteria.onoConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch method needs to pass sequence_number with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.ASkJIminnvreoorAc.Vivservice.onoNow let me check T there's an existine lesttor AskJiminnykeportaccivicyservice lo uodale:Exolored Ask.liminnvReI need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:AskJiminnyReportActivityServiceTest.phpNow let's run the test to verify:Command dockeldocker exec docker lamp 1 php /var/www/html/artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverageCould not open input file: /var/www/html/artisanCommand dockerodoste/une/ervaces/KJosk/AuF omaate/aeports/AskJiminnyReportActivityserviceTest.php --no-coverageCould not open input file: /app/artisannavicaunohVew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> CodeClaude Sonnet 4.6winasun leamsb8: /ob chars, 23 line breaksuir-o( 4 spaces...
|
11007
|
|
11011
|
217
|
62
|
2026-04-14T09:08:18.960813+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157698960_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactonToo PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.php= custom.log= laravel.loge SF (iminny@localhostL HS_local fiminny@localhost)& console (PROD]AutomatedReports(C) ActivityTypeService.(C AskJiminnyReportAc(C) AutomatedReportse(C) AutomatedReportsS© DealStagesService.p© Recipientsservice.pr@ Reportsort.php(e) Reporisonbirection.Kloskservice.php> M MailMeetingGenerator> Notification→0Auth2RecallAl_ Security_ StrategyStreamingeamTelephonyM UserPilotM Webhook© AbstractService.php© ActivityProviderFactory.phC) ActivityService.phpC ApiResponseService.php(C) ConferenceService.php© InsightSeatService.php© InstantMeetingService.phpC IntercomService.php© IpapiClient.phpC) IpapiService.phpC) ParticioantShareService.phC PlanhatService.ohpC) PlaybackService.php(C PlaybackVideoOnlyService(C) PlaybookCategoryService.C PlaylistGeneratorinterface.(C) ResolveTeamCrmConnecti© SimpleThrottleService.php© slackservice.phpC) SocialAccountService.phnC) SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php(C) TeamService.phpC) TranscodeParameterResolC UserService.phpC) Uuid.php> D Traits• → UseCases> D UserDUtils• I validation•IV0pnp nelpers.php(C InitialFrontendState.php(©) Jiminny.php(C) Plan.php© AutomatedReportsCommand.php< console LUlconsole SlAGiNGAskJiminnykepor Acuivilyservice.ono x© AutomatedReportsSendCommand.php© AddLayoutEntities.phpC AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.php<?php(©) Team.php(©) AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.php(©) CreateActivityLoggedEvent.phpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 V.4 ^* dreturn Automatedreportpublic function create(array $data): Automatee* Find an automated report bu UUID* dparam string Suuid* dreturn AutomatedReport null22public function findbyuuld(string suuid): ?Alreturn AutomatedReport::where('uuld', Aut-261 usagepublic function findByTdOrUuid string Sidorttifis numeric($id0rUuidreturn AutomatedReport: :Jind((Int) $I31return Automatedkeport: :where ("uuid", Autze* ketrieve alt standara (hon ask min e*oodrdl sarno osorccocuminThe coLumn 41*dearal string ssortosrection the sort dare 42* dreturn Collection<AutomatedReport>-4412 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at',scring ssortbireccion = "desc"CoLlectlon t...—46—4%* Retrieve all Ask Jiminny reports created tWinasurt changelog 2.12.21: A new version is avallable. # View Changelog (today 10:33,declare(strict_types=l):nanespace Jamunny servaces Klosk Autonareokedorts.luse smunny Lonoonen Acewtsearch rurerverin cion AcauvActuauuairenuse Jiminny Component ActivitySearch FilterDefinition ActivityUpdatedDate:use Jiminny Component ActivitySearch FilterDefinition DealInsights ClosingPeriodFilter:use Jiminny Component ActivitySearch Service ActivitySearch:use Jiminny Models Activity Search;use Jiminny Models Useruse Jiminny Repos1tor1es Elast1cAct1v1tyRepos1tory:use Jiminny vu keposttory\unbemandaculVitysearcn criteria;use PsryLog Loggerintertace;8 usagesclass AskJiminnyReportActivityServicecascade "tlCommand&Tusageprivate const int DEFAULT TOP ACTIVITIES COUNT = 100:1 usageprivate const array [ENV_SECRET],ACCIVItyACCUaLDaCe: :PARAM_END_DATEAcuIvityupdacedbace::PARAN_UPDATEU_FRON,ACuNLTVUDOareOUaTe::PAKAM UPUAIEU 10.Llosingrertoaricter..ner_orAKl_bAle,Losnoreroortuterxer Nu DAne.1:1 usagepublic function __constructlprivate readonly Activitysearch sactivitysearchprivate readonly ElasticActivityRepos1tory selasticrepositoryprivate readonly Loggerintertace slogger,) 1..3xx* Fetch activitu IDs for a saved search. passina its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist.* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* [* @return string[] Activity IDs*/ [14 usagespublic function getActivityldsForsavedsearchsearch ssavedsearch,user suser): array {nreouestrarallis = us-70uloke.uestraraisrrolbearchosaveooearchr suserorScriteria = Criteria::createFromRequest(AccepuRenectsrequescrarams,L'LInit => seLt::UEFAULI_TUP_ACTIVITLES_CUUNl,array_merge ($redJestPaYaV Accept File &-X-Reject File #33T0P ACTTVITTES COUNTa Support Daily • in 2h 52 m100% |45]Tue 14 Apr 12:08:18L AskJiminnyReportActivityServiceT….DefaultsCascadeFixing ReportControlleAutomated Report MaiFixing Ask Jiminny P+D ...Now l see the full picture. Let me also check ActivityDurationRange and ActivityRecorded defaults for isFirstRequest():kead Activityduradionkange.ono ana Acuivitykecorded.onpNow have the comolete root cause victure. This is critical.Root Cause FoundIhe bui LakequestParamstromsearch method in AskuaminnykeportActivityservice passes sequence_number= Implicitly (not in params), Wnich meansisFirstRequest( returns trueWhen sequence number is notin reguestParams, the Criteria:: createFromRequest defaultsitto 0,and isFirstRequest() returns true when empty 1lsequenceNumber == 0.The frontend URL has sequence number=4 - meaning it's not a first request. The service doesn't set it, so the criteria thinks it's a first request.Wnen 1SF1rstRequest = true, these Implicht tilers are apolled that aren tin the saved search:1. ActivityDurationRange— applies min duration = 1 (INITIAL MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - Tilters to recorded-only3. OrganiserGroupIn - applies user's default group filterburtne Tronteno Wiun sequence numberza skiosal or nese cecurs, so trerurns more resuisThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence number in the merge in getActivityIdsForSavedSearch.Read Ask.liminnvRenortActivitvService.nno #44-93Now let me verity my understanding of isFirstRequest:Read Criteria.phpConfirmed. The fix is clear and minimal. The getAct.ivitvIdsForSavedSearch method needs to pass sequence number with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.AskJiminnyReportActivityService.php+1 -1Now let me check if there's an existing test for AskJiminnyReportActivityService to update:=xo oree ASkJlminnvkeImeed oraddan est narevermes seouence numberel stoassed orusenrsossanis keqesiao recumns ta lseo. cemerado onnerex stino estaile• AskJiminnyReportActivityServicelest.phpNow let's run the test to verify:Command dockerdesks/uext/sdrvkces/K10sk/Automate/mep/rts/Asktiman yespcomaceareports/ AskJiminnyreportaccivityservicelest.ono =-no-coveraacould not open input tile: /var/www/html/artisanCommand dockero teste/unxt/ drvaees/Ko5k/Autonate/aeports/ASk3-1minnyReportActivityserviceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerdesker ext/ drvkees/K1osk /AusonatedReports/AskJiminnvReportActivitvServiceTest,php --no-coverage 2>61'sallineVew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (&+L)+ ‹> CodeClaude Sonnet 4.6winasun leams1/:l2046 chars, /s line breaksuir-oia 4 spacesew...
|
NULL
|
-6507571708961195058
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactonToo PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.php= custom.log= laravel.loge SF (iminny@localhostL HS_local fiminny@localhost)& console (PROD]AutomatedReports(C) ActivityTypeService.(C AskJiminnyReportAc(C) AutomatedReportse(C) AutomatedReportsS© DealStagesService.p© Recipientsservice.pr@ Reportsort.php(e) Reporisonbirection.Kloskservice.php> M MailMeetingGenerator> Notification→0Auth2RecallAl_ Security_ StrategyStreamingeamTelephonyM UserPilotM Webhook© AbstractService.php© ActivityProviderFactory.phC) ActivityService.phpC ApiResponseService.php(C) ConferenceService.php© InsightSeatService.php© InstantMeetingService.phpC IntercomService.php© IpapiClient.phpC) IpapiService.phpC) ParticioantShareService.phC PlanhatService.ohpC) PlaybackService.php(C PlaybackVideoOnlyService(C) PlaybookCategoryService.C PlaylistGeneratorinterface.(C) ResolveTeamCrmConnecti© SimpleThrottleService.php© slackservice.phpC) SocialAccountService.phnC) SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php(C) TeamService.phpC) TranscodeParameterResolC UserService.phpC) Uuid.php> D Traits• → UseCases> D UserDUtils• I validation•IV0pnp nelpers.php(C InitialFrontendState.php(©) Jiminny.php(C) Plan.php© AutomatedReportsCommand.php< console LUlconsole SlAGiNGAskJiminnykepor Acuivilyservice.ono x© AutomatedReportsSendCommand.php© AddLayoutEntities.phpC AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.php<?php(©) Team.php(©) AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.php(©) CreateActivityLoggedEvent.phpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 V.4 ^* dreturn Automatedreportpublic function create(array $data): Automatee* Find an automated report bu UUID* dparam string Suuid* dreturn AutomatedReport null22public function findbyuuld(string suuid): ?Alreturn AutomatedReport::where('uuld', Aut-261 usagepublic function findByTdOrUuid string Sidorttifis numeric($id0rUuidreturn AutomatedReport: :Jind((Int) $I31return Automatedkeport: :where ("uuid", Autze* ketrieve alt standara (hon ask min e*oodrdl sarno osorccocuminThe coLumn 41*dearal string ssortosrection the sort dare 42* dreturn Collection<AutomatedReport>-4412 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at',scring ssortbireccion = "desc"CoLlectlon t...—46—4%* Retrieve all Ask Jiminny reports created tWinasurt changelog 2.12.21: A new version is avallable. # View Changelog (today 10:33,declare(strict_types=l):nanespace Jamunny servaces Klosk Autonareokedorts.luse smunny Lonoonen Acewtsearch rurerverin cion AcauvActuauuairenuse Jiminny Component ActivitySearch FilterDefinition ActivityUpdatedDate:use Jiminny Component ActivitySearch FilterDefinition DealInsights ClosingPeriodFilter:use Jiminny Component ActivitySearch Service ActivitySearch:use Jiminny Models Activity Search;use Jiminny Models Useruse Jiminny Repos1tor1es Elast1cAct1v1tyRepos1tory:use Jiminny vu keposttory\unbemandaculVitysearcn criteria;use PsryLog Loggerintertace;8 usagesclass AskJiminnyReportActivityServicecascade "tlCommand&Tusageprivate const int DEFAULT TOP ACTIVITIES COUNT = 100:1 usageprivate const array [ENV_SECRET],ACCIVItyACCUaLDaCe: :PARAM_END_DATEAcuIvityupdacedbace::PARAN_UPDATEU_FRON,ACuNLTVUDOareOUaTe::PAKAM UPUAIEU 10.Llosingrertoaricter..ner_orAKl_bAle,Losnoreroortuterxer Nu DAne.1:1 usagepublic function __constructlprivate readonly Activitysearch sactivitysearchprivate readonly ElasticActivityRepos1tory selasticrepositoryprivate readonly Loggerintertace slogger,) 1..3xx* Fetch activitu IDs for a saved search. passina its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist.* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* [* @return string[] Activity IDs*/ [14 usagespublic function getActivityldsForsavedsearchsearch ssavedsearch,user suser): array {nreouestrarallis = us-70uloke.uestraraisrrolbearchosaveooearchr suserorScriteria = Criteria::createFromRequest(AccepuRenectsrequescrarams,L'LInit => seLt::UEFAULI_TUP_ACTIVITLES_CUUNl,array_merge ($redJestPaYaV Accept File &-X-Reject File #33T0P ACTTVITTES COUNTa Support Daily • in 2h 52 m100% |45]Tue 14 Apr 12:08:18L AskJiminnyReportActivityServiceT….DefaultsCascadeFixing ReportControlleAutomated Report MaiFixing Ask Jiminny P+D ...Now l see the full picture. Let me also check ActivityDurationRange and ActivityRecorded defaults for isFirstRequest():kead Activityduradionkange.ono ana Acuivitykecorded.onpNow have the comolete root cause victure. This is critical.Root Cause FoundIhe bui LakequestParamstromsearch method in AskuaminnykeportActivityservice passes sequence_number= Implicitly (not in params), Wnich meansisFirstRequest( returns trueWhen sequence number is notin reguestParams, the Criteria:: createFromRequest defaultsitto 0,and isFirstRequest() returns true when empty 1lsequenceNumber == 0.The frontend URL has sequence number=4 - meaning it's not a first request. The service doesn't set it, so the criteria thinks it's a first request.Wnen 1SF1rstRequest = true, these Implicht tilers are apolled that aren tin the saved search:1. ActivityDurationRange— applies min duration = 1 (INITIAL MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - Tilters to recorded-only3. OrganiserGroupIn - applies user's default group filterburtne Tronteno Wiun sequence numberza skiosal or nese cecurs, so trerurns more resuisThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence number in the merge in getActivityIdsForSavedSearch.Read Ask.liminnvRenortActivitvService.nno #44-93Now let me verity my understanding of isFirstRequest:Read Criteria.phpConfirmed. The fix is clear and minimal. The getAct.ivitvIdsForSavedSearch method needs to pass sequence number with a non-zero value so that isFirstRequest() returns false and no implicit defaults are applied.AskJiminnyReportActivityService.php+1 -1Now let me check if there's an existing test for AskJiminnyReportActivityService to update:=xo oree ASkJlminnvkeImeed oraddan est narevermes seouence numberel stoassed orusenrsossanis keqesiao recumns ta lseo. cemerado onnerex stino estaile• AskJiminnyReportActivityServicelest.phpNow let's run the test to verify:Command dockerdesks/uext/sdrvkces/K10sk/Automate/mep/rts/Asktiman yespcomaceareports/ AskJiminnyreportaccivityservicelest.ono =-no-coveraacould not open input tile: /var/www/html/artisanCommand dockero teste/unxt/ drvaees/Ko5k/Autonate/aeports/ASk3-1minnyReportActivityserviceTest.php --no-coverageCould not open input file: /app/artisanCommand dockerdesker ext/ drvkees/K1osk /AusonatedReports/AskJiminnvReportActivitvServiceTest,php --no-coverage 2>61'sallineVew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (&+L)+ ‹> CodeClaude Sonnet 4.6winasun leams1/:l2046 chars, /s line breaksuir-oia 4 spacesew...
|
NULL
|
|
11013
|
217
|
63
|
2026-04-14T09:08:22.537545+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157702537_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8043719072324535154
|
-8628527368849355612
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
PhpStormFileFditViewNavig Project: faVsco.js, menu
PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vc) ReportController.onp© JiminnyDebugCommand.php= custom.log= laravel.loge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]AutomatedReports(C) ActivityTypeService.(C AskJiminnyReportAc(C) AutomatedReportse(C) AutomatedReportsS© DealStagesService.p© Recipientsservice.pr@ Reportsort.php(e) Reporisonbirection.Kloskservice.php> M MailMeetingGenerator› Notification→0Auth2l RecallAl_ Security_ Strategy_ StreamingeamTelephonyM UserPilotM Webhook© AbstractService.php© ActivityProviderFactory.phC) ActivityService.phpC ApiResponseService.php(C) ConferenceService.php© InsightSeatService.php© InstantMeetingService.phpC IntercomService.php© IpapiClient.phpC) IpapiService.phpC) ParticioantShareService.phC PlanhatService.ohp(C) PlaybackService.php(C PlaybackVideoOnlyService(C) PlaybookCategoryService.lC PlaylistGeneratorinterface(C) ResolveTeamCrmConnectiC SimpleThrottleService.php© SlackService.phpC) SocialAccountService.phnC) SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php(C) TeamService.php(C) TranscodeParameterResolC UserService.phpC) Uuid.php> D Traits• → UseCases> D UserDUtils• I validation•IV0pnp nelpers.php(C InitialFrontendState.php(©) Jiminny.php(C) Plan.php© AutomatedReportsCommand.php< console EUi4 console [STAGING]AskJiminnykeporAcuivilyservice.ong x© AutomatedReportsSendCommand.phpC AddLayoutEntities.phpCh Ask.JiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.php(C) Team.php(©) AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.php(©) CreateActivityLoggedEvent.phpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.phpC RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 V.4 ^* dreturn Automatedreportpublic function create(array $data): Automat: 27* Find an automated report bu UUID* @param string Suuid32* dreturn AutomatedReport nullpublic function findByUuid(string $uuid): ?A136return AutomatedReport::where('uvid', Aut38—391 usagepublic function findByTdOrUuidstring $id0rüt 42ifis numeric($id0rUuidreturn AutomatedReport:: find((int) $j44return AutomatedReport::where('uu1d', AUt41* Recrieve alc scandara (non-Ask Jiminny) al*oodrdl sarno osorccocuminThe column to*dearal string ssortosrection the sort dare* dreturn Collection<AutomatedReport>— 5612 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at',scring ssortbireccion = "desc"CoLlectlon t...use PsryLog Loggerintertace;o usagesclass AskJiminnyReportActivityService—585960— 6173* Retrieve all Ask Jiminny reports created t°3Winasurt changelog 2.12.21: A new version is avallable. # View Changelog (today 10:33,lusaeeprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100:1 usageprivate const array [ENV_SECRET],ACuIVItyACcUaLbaCe::PARAM_END_DAIEActivitvUodatedDate::PARAM UPDATED FROM.IActivityUodatedDate::PARAM UPDATED TO.Extract SurroundClosingPeriodFilter::KEY START DATE.closinorer1ouriuter..kcrcNu DAlc,]:1 usagepublic function -_constructlprivate readonly Activitysearch Sactivitysearch.private readonly ElasticActivitykeposicory selasclckepos1tory.private readonly Loggerintertace slogger,) 4.3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist.* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte*creturn stringl. Activity Ibs*/14 usagespublic function getActivityIdsForSavedSearch(search ssavedsearch,user puser,): array €mrecuestraralis = ms-70ucokecuestraraliisrrolbearcilnsaveosearchrouserorScriteria = Criteria::createFromRequestAccepuRenect,requescrarams, L'uImit => seLt:: DEFAULI_TUP_ACTIVITLES_CUUNI, 'page" =array_mergelsrequescraramsL" L1n1u => SeLT::DEFAULI_10P_ACIIVLILES_COUN/.page" Fpuser-›geclimezone)$filterSet = $this->activitvSearch->aetOnDemandPaaefilterSet(Scriteria,l suser):SactivityIds = sthis->elasticRepository->onDemandSearchIds0nlySuser, Scriteria, sfilter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [saved_search_1d => $savedsearch->getid(),'user_1d => suser->getia),'activity count'=> count(sactivitylds),1):notiinn santivit!/ Accept File &+X Reject File 1 38 €a Support Daily • in 2h 52 mA100% [2Tue 14 Apr 12:08:22L AskJiminnyReportActivityServiceT….DefaultsCascadeFixing ReportControlleiAutomated Report Mai© Fixing Ask Jiminny PNow l see the full picture. Let me also check ActivityDurationRange and ActivityRecorded defaults for isFirstRequest():kead Activityduradionkange.ono ana Acuivitykecorded.onpNow |have the comolete root cause picture. This is critica.Root Cause FoundIDtemItoke a est atans aion eaTdi me oe inTASKE iVKeDOT VATa owat vservceloassies sequence numberemolcuvaino Uht oalamsirWnlIchImeahsisFirstRequest() returns trueWhen sequence number is notin requestParams, the Criteria:: createFromRequest defaultsitto 0,and isFirstRequest() returns true when empty 1lsequenceNumber == 0.The frontend URL has sequence number=4 - meaning it's not a first request. The service doesn't set it, so the criteria thinks it's a first request.Wnen 1SF1rstRequest = true, these Implicht tilers are apolled that aren tin the saved search:1. ActivityDurationRange— applies min duration = 1 (INITIAL MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-only3. OrganiserGroupIn - applies user's default group filterburthe Tronteno Wiun sequence numberza skiosalll or nese ceaurs so trerurns more resuisThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitderauts dont agoy. Ur alernatvely, always gass a nohzzero sequence nunder in the mergein detactlvltysastorsavedsearchh.Now let me verify my understanding of isFirstRequest :Read Criteria.phpCoimeor inenxasteea alnlalr lnel e Ata ewhwsorveseananme noo eeust olass sequence number winrnonzzero value sonnaleisiauistRequest() returns false and no implicit defaults are applied.• AskJiminnyReportA÷1-1|Now let me check if there's an existing test for AskJiminnyReportActivityService to update:=xolore. Ask.iminnvreoonActvivserviceles.ono and searche. Ask./lminnvreoor Acuvi"Interecnoraodrn (est anaevernes sequence numbere stoasseo oluieme sossanske esdo euns a seonre merdcueonerex sie estanteAskJiminnvrepor.acuvilyserMcerest.onpNow let's run the test to verify:tests/unxt/sdrvkces/K105k/Automatr/mep/rts/Asktiman yRsportActivityserviceTest php --no-coverageCould not open input Tile: /var/www/html/artisancommana aockelteste/unit/Serutces/x4psk/AutofaperBenosts/Ask1iminnvReportActivitvServiceTest.pho eeno-coveraaetests/Unit/Services/KidLoula nor open Inpuc Tile: app arcisanCommand dockerewnnvrevortAcnvtsercel estono =-no-coverade zolItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (&+L)+ <> Code Claude Sonnet 4.6Run &&+SkipVew allliReject allAccept allW Windsur leams24:49uir-oia 4 spaces...
|
11011
|
|
11018
|
217
|
66
|
2026-04-14T09:08:33.374866+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157713374_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]v _ ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.php© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php X<?php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrdeclare(strict_types=1);C DeallnsightsPeriodFilter(e) TrackProvidernstallled-vent.ono0 DealinsidnisPeriodriltennanespace Jamunny conoonent Acuvurvsearchservice.g FilterDetinition.php© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpc rterverntoncolectousec rterverntoncuev.on© FilterDefinitionQueryColclass ActivitySearch© AutomatedReportResult.php• FilteredValueContainerli© IntMinMaxRange.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php[ AiActivityTypeclass Automacedкeрortskepo o:B15 X4 ^7 usagesprivate Container $container;[ AiAutomationD AiCallScoringpublic function __construct(Container $container){.}* Oreturn AutomatedReportD AskAnythingD AskJiminnyAipublic function getOnDemandPageFilters(): FilterDefinitionCollectionf...}DAWS• BillingManagementCache• CoachingFeedback> D CountryD CustomerApi35373839• DatabaseC DatadogC DateTimeDeallnsights• Dealkisks> IEasuicsearchpublic function create(array $data): Automate106107/**-108* Find an automated report by UUID109110* @param string $uvid111112* Oreturn AutomatedReport|null113114public function findByUuid(string $uvid): ?Al]115return AutomatedReport: :where('uvid', Aut118public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):› D Eloquent> DEncoding9 usages1 usage> M Encryption117public function getArrayFilterKeys(User $consumer): arrayf...}DESpubLie tunction tinabytaurousdlstring eiaurul 136> D Faker1 usage• FeatureFlagsif (is_numeric($id0rUuid)) {return AutomatedReport:: find((int) $1]private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecO FFMpeg• FileSystemD GeckoD GongGuzzleHttp198return AutomatedReport: :where('uvid', Aut199200KeyPoints• Kiosk1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}M LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot_ MobileSettings| ModelNotiticationD Nudge> D ParagraphBreakerM ParticipantSpeechPartitionedCookie12402* Retrieve all standard (non-ASk Liminay) al 232*oodrdl sarno osorccocumin233The column tl 234*Cearal string ssorcosrection the sort a1m235236* Oreturn Collection<AutomatedReport>237— 24412 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection f...}/**245— 2462471248public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}D PlaybackPageD PlaylistL07* Retrieve all ASK Lininny reports created k2601 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerWindsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)Support Daily • in 2h 52mAL AskJiminnyReportActivityServiceT...Defaults100% |45]Tue 14 Apr 12:08:33+D ...CascadeFixing ReportControllerAutomated Renort Ma• Fixing Ask Jiminny RRead ActivityDurationRange.php and ActivityRecorded.phpNow I have the complete root cause picture. This is critical:Root Cause FoundThe buildRequestParamsFromSearch method in AskJiminnyReportActivityService passes sequence_number=0 implicitly (not in params), which meansusFurstrequest rerurns trueWhen sequence_number is not in requestParams, the Criteria::createFromRequest defaults it to 0, and isFirstRequest() returns true when empty 11sequenceNumber == 0.ine Tronenc Urunas sequence number=d- neanino ils nora Tistreouest, Ine service •oesh't serr, so the crlera thinks u's a tistrecuestWhen isFirstRequest() = true , these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange— applies min duration = 1 (INITIAL MIN) - filters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) — filters to recorded-oniy3, Oroansercroupin —aoollesuser's ceaur orouo titerBut the frontend with sequence_number=4 skips all of these defaults, so it returns more results.Tneiix shoulo dennoue wokequest diatamsiaromsertidi- neeas orpass seauence numbernine oultparamsio siana notamrstrequest sonnelimolicitdefaults don't apply. Or alternatively, always pass a non-zero sequence_number in the merge in getActivityIdsForSavedSearch.Read AskJiminnykepor ActiVilyse.Now let me verify my understanding of isFirstRequest :Read Criteria.ohnConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch method needs to pass sequence number with a non-zero value so that isFirstRequest() returns false and no imolicit defaults are apolied.• AskJiminnyReportActivityService.php+1 -1Now let me check if there's an existing test for AskJiminnyReportActivityService to update:Explored AskJiminnyRe1іи1.1518428182241898845828588885888818812I need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:• AskJiminnyReportActivityServiceTest.php+2/Now let's run the test to verify:commana dockeldocker_doste/nke/ tockces/klosk/Ru /ar/ep/rts/AKzinanyReportActivityServacetest-php -no-coverageCould not open input file: /var/www/html/artisanCommand docker• docker exec docker_lamp_1 php /app/artisan testrests unleservlces Klosk Altonareoredorts askamnnvrevortacuvtsercel estono --no-coveradeCould not open input file: /app/artisanCommand dockeno destsrext/Serukees/K1os1 Automate®Reports/Ask im phpReportAc tvstes/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisanNavigating..eItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams11O:24uir-o( 4 spaces...
|
NULL
|
-600025735675103094
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]v _ ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.php© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php X<?php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrdeclare(strict_types=1);C DeallnsightsPeriodFilter(e) TrackProvidernstallled-vent.ono0 DealinsidnisPeriodriltennanespace Jamunny conoonent Acuvurvsearchservice.g FilterDetinition.php© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpc rterverntoncolectousec rterverntoncuev.on© FilterDefinitionQueryColclass ActivitySearch© AutomatedReportResult.php• FilteredValueContainerli© IntMinMaxRange.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php[ AiActivityTypeclass Automacedкeрortskepo o:B15 X4 ^7 usagesprivate Container $container;[ AiAutomationD AiCallScoringpublic function __construct(Container $container){.}* Oreturn AutomatedReportD AskAnythingD AskJiminnyAipublic function getOnDemandPageFilters(): FilterDefinitionCollectionf...}DAWS• BillingManagementCache• CoachingFeedback> D CountryD CustomerApi35373839• DatabaseC DatadogC DateTimeDeallnsights• Dealkisks> IEasuicsearchpublic function create(array $data): Automate106107/**-108* Find an automated report by UUID109110* @param string $uvid111112* Oreturn AutomatedReport|null113114public function findByUuid(string $uvid): ?Al]115return AutomatedReport: :where('uvid', Aut118public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):› D Eloquent> DEncoding9 usages1 usage> M Encryption117public function getArrayFilterKeys(User $consumer): arrayf...}DESpubLie tunction tinabytaurousdlstring eiaurul 136> D Faker1 usage• FeatureFlagsif (is_numeric($id0rUuid)) {return AutomatedReport:: find((int) $1]private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecO FFMpeg• FileSystemD GeckoD GongGuzzleHttp198return AutomatedReport: :where('uvid', Aut199200KeyPoints• Kiosk1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}M LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot_ MobileSettings| ModelNotiticationD Nudge> D ParagraphBreakerM ParticipantSpeechPartitionedCookie12402* Retrieve all standard (non-ASk Liminay) al 232*oodrdl sarno osorccocumin233The column tl 234*Cearal string ssorcosrection the sort a1m235236* Oreturn Collection<AutomatedReport>237— 24412 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection f...}/**245— 2462471248public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}D PlaybackPageD PlaylistL07* Retrieve all ASK Lininny reports created k2601 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerWindsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)Support Daily • in 2h 52mAL AskJiminnyReportActivityServiceT...Defaults100% |45]Tue 14 Apr 12:08:33+D ...CascadeFixing ReportControllerAutomated Renort Ma• Fixing Ask Jiminny RRead ActivityDurationRange.php and ActivityRecorded.phpNow I have the complete root cause picture. This is critical:Root Cause FoundThe buildRequestParamsFromSearch method in AskJiminnyReportActivityService passes sequence_number=0 implicitly (not in params), which meansusFurstrequest rerurns trueWhen sequence_number is not in requestParams, the Criteria::createFromRequest defaults it to 0, and isFirstRequest() returns true when empty 11sequenceNumber == 0.ine Tronenc Urunas sequence number=d- neanino ils nora Tistreouest, Ine service •oesh't serr, so the crlera thinks u's a tistrecuestWhen isFirstRequest() = true , these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange— applies min duration = 1 (INITIAL MIN) - filters out 0-second calls2. ActivityRecorded - applies only recorded = 1 (DEFAULT VALUE = OPTION RECORDED) — filters to recorded-oniy3, Oroansercroupin —aoollesuser's ceaur orouo titerBut the frontend with sequence_number=4 skips all of these defaults, so it returns more results.Tneiix shoulo dennoue wokequest diatamsiaromsertidi- neeas orpass seauence numbernine oultparamsio siana notamrstrequest sonnelimolicitdefaults don't apply. Or alternatively, always pass a non-zero sequence_number in the merge in getActivityIdsForSavedSearch.Read AskJiminnykepor ActiVilyse.Now let me verify my understanding of isFirstRequest :Read Criteria.ohnConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch method needs to pass sequence number with a non-zero value so that isFirstRequest() returns false and no imolicit defaults are apolied.• AskJiminnyReportActivityService.php+1 -1Now let me check if there's an existing test for AskJiminnyReportActivityService to update:Explored AskJiminnyRe1іи1.1518428182241898845828588885888818812I need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:• AskJiminnyReportActivityServiceTest.php+2/Now let's run the test to verify:commana dockeldocker_doste/nke/ tockces/klosk/Ru /ar/ep/rts/AKzinanyReportActivityServacetest-php -no-coverageCould not open input file: /var/www/html/artisanCommand docker• docker exec docker_lamp_1 php /app/artisan testrests unleservlces Klosk Altonareoredorts askamnnvrevortacuvtsercel estono --no-coveradeCould not open input file: /app/artisanCommand dockeno destsrext/Serukees/K1os1 Automate®Reports/Ask im phpReportAc tvstes/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisanNavigating..eItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams11O:24uir-o( 4 spaces...
|
NULL
|
|
11019
|
217
|
67
|
2026-04-14T09:08:39.409070+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157719409_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]v _ ServiceAulomaleakeporscommand.ono< console EUiconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.php© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php X<?php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrdeclare(strict_types=1);C DeallnsightsPeriodFilter(e) TrackProvidernstallled-vent.ono0 DealinsidnisPeriodrilteng FilterDetinition.php© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny \Component\ActivitySearch\Service;c rterverntoncolectousec rterverntoncuev.on© FilterDefinitionQueryColclass ActivitySearch© AutomatedReportResult.php• FilteredValueContainerli© IntMinMaxRange.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(©) AutomatedReport.php[ AiActivityTypeclass Automacedкeрortskepo o:B15 X4 ^7 usagesprivate Container $container;[ AiAutomationD AiCallScoringpublic function __construct(Container $container){.}* Oreturn AutomatedReportD AskAnythingD AskJiminnyAipublic function getOnDemandPageFilters(): FilterDefinitionCollectionf...}DAWS• BillingManagementCache• CoachingFeedback> D CountryD CustomerApi35373839• DatabaseC DatadogC DateTimeDeallnsights• Dealkisks> IEasuicsearchpublic function create(array $data): Automate106107/**-108* Find an automated report by UUID109110* @param string $uvid111112* Oreturn AutomatedReport|null113114public function findByUuid(string $uvid): ?Al]115return AutomatedReport: :where('uvid', Aut118public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):› D Eloquent> DEncoding9 usages1 usage> M Encryption117public function getArrayFilterKeys(User $consumer): arrayf...}DESpubLie tunction tinabytaurousdlstring eiaurul 136> D Faker1 usage• FeatureFlagsif (is_numeric($id0rUuid)) {return AutomatedReport:: find((int) $1private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecO FFMpeg• FileSystemD GeckoD GongGuzzleHttp198return AutomatedReport: :where('uvid', Aut199200KeyPoints• Kiosk1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}M LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot_ MobileSettings| ModelNotiticationD Nudge> [ ParagraphBreakerM ParticipantSpeechPartitionedCookie12402* Retrieve all standard (non-ASk Liminay) al 232*oodrdl sarno osorccocumin233The column tl 234*Cearal string ssorcosrection the sort a1m235236* Oreturn Collection<AutomatedReport>237— 24412 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection f...}/**245— 2462471248public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}D PlaybackPageD PlaylistL07* Retrieve all ASK Lininny reports created k2601 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,usen sconsumenWindsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)j Support Daily • in 2h 52mAL AskJiminnyReportActivityServiceT..Defaults100% C•Tue 14 Apr 12:08:39CascadeFixing ReportControllerAutomated Report Mai© Fixing Ask Jiminny R+D ...Une bun Lakequestraramst romsearch metnod in AskJaminnykeportAct lvlcyservice passes sequence number= Impllcity (not in params , Wnich meansisFirstRequest() returns true.When sequence_number is not in requestParams, the Criteria:: createFromRequest defaultsit to 0, and isFirstRequest() returns true when empty 11sequencenumber == 0.The frontend URL has sequence_number=4 — meaning it's not a first request. The service doesn't set it, so the criteria thinks it's a first request.When isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange— applies min duration = 1 (INITIAL MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-only3. OrganiserGroupIn - applies user's default group filterbut the Trontend With sequence number=4 sklos all or these derauls, so it returns more resuitsThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence_ number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence number in the merge in getActivityIdsForSavedSearchNow let me verify my understanding of isFirstRequest:Read Criteria.phpcontirmed. Ine Tix is clear and minimal. Ine qetacuntylasForsavedsearch method needs to pass sequence_number With a non-zero value so that isrirstRequest() returns false and no implicit defaults are applied.• AskJiminnyReportAc)Now let me check if there's an existing test for AskJiminnyReportActivityService to update:Explored AskJiminnyReportActivityServiceTest.php and searched AskJiminnyReportActivity*I need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:• AskJiminnyReporNow let's run the test to verirytests/unxt/servaces/K105k/AutomeCould not open input file: /var/www/html/artisandReports/AskJiminnyReportActivityServiceTest.php --no-coveragedocker exec docker_lamp_1 php /app/artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisandocker exec docker_lamp_1 bash -c "cd /var/www && php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisanCommand dockero docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Munae+ SkipView allReject allAccept allwinasur leams110:24uir-o( 4 spaces...
|
NULL
|
-5895872733280284593
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]v _ ServiceAulomaleakeporscommand.ono< console EUiconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.php© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php X<?php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrdeclare(strict_types=1);C DeallnsightsPeriodFilter(e) TrackProvidernstallled-vent.ono0 DealinsidnisPeriodrilteng FilterDetinition.php© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny \Component\ActivitySearch\Service;c rterverntoncolectousec rterverntoncuev.on© FilterDefinitionQueryColclass ActivitySearch© AutomatedReportResult.php• FilteredValueContainerli© IntMinMaxRange.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(©) AutomatedReport.php[ AiActivityTypeclass Automacedкeрortskepo o:B15 X4 ^7 usagesprivate Container $container;[ AiAutomationD AiCallScoringpublic function __construct(Container $container){.}* Oreturn AutomatedReportD AskAnythingD AskJiminnyAipublic function getOnDemandPageFilters(): FilterDefinitionCollectionf...}DAWS• BillingManagementCache• CoachingFeedback> D CountryD CustomerApi35373839• DatabaseC DatadogC DateTimeDeallnsights• Dealkisks> IEasuicsearchpublic function create(array $data): Automate106107/**-108* Find an automated report by UUID109110* @param string $uvid111112* Oreturn AutomatedReport|null113114public function findByUuid(string $uvid): ?Al]115return AutomatedReport: :where('uvid', Aut118public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):› D Eloquent> DEncoding9 usages1 usage> M Encryption117public function getArrayFilterKeys(User $consumer): arrayf...}DESpubLie tunction tinabytaurousdlstring eiaurul 136> D Faker1 usage• FeatureFlagsif (is_numeric($id0rUuid)) {return AutomatedReport:: find((int) $1private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecO FFMpeg• FileSystemD GeckoD GongGuzzleHttp198return AutomatedReport: :where('uvid', Aut199200KeyPoints• Kiosk1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}M LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot_ MobileSettings| ModelNotiticationD Nudge> [ ParagraphBreakerM ParticipantSpeechPartitionedCookie12402* Retrieve all standard (non-ASk Liminay) al 232*oodrdl sarno osorccocumin233The column tl 234*Cearal string ssorcosrection the sort a1m235236* Oreturn Collection<AutomatedReport>237— 24412 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection f...}/**245— 2462471248public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}D PlaybackPageD PlaylistL07* Retrieve all ASK Lininny reports created k2601 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,usen sconsumenWindsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)j Support Daily • in 2h 52mAL AskJiminnyReportActivityServiceT..Defaults100% C•Tue 14 Apr 12:08:39CascadeFixing ReportControllerAutomated Report Mai© Fixing Ask Jiminny R+D ...Une bun Lakequestraramst romsearch metnod in AskJaminnykeportAct lvlcyservice passes sequence number= Impllcity (not in params , Wnich meansisFirstRequest() returns true.When sequence_number is not in requestParams, the Criteria:: createFromRequest defaultsit to 0, and isFirstRequest() returns true when empty 11sequencenumber == 0.The frontend URL has sequence_number=4 — meaning it's not a first request. The service doesn't set it, so the criteria thinks it's a first request.When isFirstRequest() = true, these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange— applies min duration = 1 (INITIAL MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-only3. OrganiserGroupIn - applies user's default group filterbut the Trontend With sequence number=4 sklos all or these derauls, so it returns more resuitsThe fix should be in buildRequestParamsFromSearch - it needs to pass sequence_ number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence number in the merge in getActivityIdsForSavedSearchNow let me verify my understanding of isFirstRequest:Read Criteria.phpcontirmed. Ine Tix is clear and minimal. Ine qetacuntylasForsavedsearch method needs to pass sequence_number With a non-zero value so that isrirstRequest() returns false and no implicit defaults are applied.• AskJiminnyReportAc)Now let me check if there's an existing test for AskJiminnyReportActivityService to update:Explored AskJiminnyReportActivityServiceTest.php and searched AskJiminnyReportActivity*I need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:• AskJiminnyReporNow let's run the test to verirytests/unxt/servaces/K105k/AutomeCould not open input file: /var/www/html/artisandReports/AskJiminnyReportActivityServiceTest.php --no-coveragedocker exec docker_lamp_1 php /app/artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisandocker exec docker_lamp_1 bash -c "cd /var/www && php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisanCommand dockero docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Munae+ SkipView allReject allAccept allwinasur leams110:24uir-o( 4 spaces...
|
11018
|
|
11021
|
NULL
|
0
|
2026-04-14T09:08:42.495739+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157722495_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]v _ ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.php© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php X<?php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrdeclare(strict_types=1);C DeallnsightsPeriodFilter(e TrackProvidernstallled-vent.ono0 DealinsidnisPeriodrilteng FilterDetinition.php© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny \Component\ActivitySearch\Service;c rterverntoncolectousec rterverntoncuev.on© FilterDefinitionQueryColclass ActivitySearch© AutomatedReportResult.php• FilteredValueContainerli© IntMinMaxRange.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php[ AiActivityTypeclass Automacedкeрortskepo o:B15 X4 ^7 usagesprivate Container $container;[ AiAutomationD AiCallScoringpublic function __construct(Container $container){.}* Oreturn AutomatedReportD AskAnythingD AskJiminnyAipublic function getOnDemandPageFilters(): FilterDefinitionCollectionf...}DAWS• BillingManagementCache• CoachingFeedback> D CountryD CustomerApi35373839• DatabaseC DatadogC DateTimeDeallnsights• Dealkisks> IEasuicsearchpublic function create(array $data): Automate106107/**-108* Find an automated report by UUID109110* @param string $uvid111112* Oreturn AutomatedReport|null113114public function findByUuid(string $uvid): ?Al]115return AutomatedReport: :where('uvid', Aut118public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):› D Eloquent> DEncoding9 usages1 usage> M Encryption117public function getArrayFilterKeys(User $consumer): arrayf...}DESpubLie tunction tinabytaurousdlstring eiaurul 136> D Faker1 usage• FeatureFlagsif (is_numeric($id0rUuid)) {return AutomatedReport:: find((int) $1]private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecO FFMpeg• FileSystemD GeckoD GongGuzzleHttp198return AutomatedReport: :where('uvid', Aut199200KeyPoints• Kiosk1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}M LanquageDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot_ MobileSettings| ModelNotiticationD Nudge> [ ParagraphBreakerM ParticipantSpeechPartitionedCookie12402* Retrieve all standard (non-ASk Liminay) al 232*oodrdl sarno osorccocumin233The column tl 234*Cearal string ssorcosrection the sort a1m235236* Oreturn Collection<AutomatedReport>237— 24412 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection f...}/**245— 2462471248public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}D PlaybackPageD PlaylistL07* Retrieve all ASK Lininny reports created k2601 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerWindsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)Support Daily • in 2h 52mAL AskJiminny ReportActivityServiceT...Defaults100% C•Tue 14 Apr 12:08:42+D ...CascadeFixing ReportControllerAutomated Report Mar• Fixing Ask Jiminny RRoot Cause FoundThe buildRequestParamsFromSearch method in AskJiminnyReportActivityService passes sequence _number=0 implicitly (not in params), which meansisFirstRequest( returns true.When sequence_number is not in requestParams, the Criteria:: CreateFromkequest defaults it to 0, and isFirstRequest() returns true when empty I1sequenceNumber === 0.The frontend URL has sequence number=4— meaning it's not a first request. The service doesn't set it, so the criteria thinks it's a first request.Wnen 1srirstrequest = true.nese mollicttites are adalled tnar aren un tne saveo searehs" Acuvltylurar lonkande — aooles min curation = 1 lINAL MIN - tIters ourO-secono callls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-only3. OrganiserGroupIn - applies user's default group filterBut the frontend with sequence_number=4 skips all of these defaults, so it returns more results.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitdefaults don't apolv. Or alternatively, alwavs pass a non-zero sequence number in the merge in getAct.ivitvIdsForSavedSearch.Read AskJiminnyReportActivityService.php #L44-93Now let me verify my understanding of isFirstRequest:Reao crierla,onoConfirmed. The fix is clear and minimal. The getAivityIdsForSavedSearch method needs to pass sequence_number with a non-zero value so that isFirstRequest () returns false and no implicit defaults are applied.• AskJiminnyReportActivityService.php+I-1Now let me check if there's an existing test for AskJiminnyReportActivityService to update:ExploredAskJiminnvReoortActivtvServicelest.onv and searchedAsk.iminnvReoortActivitvI need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:• AskJiminnyReportActivityServiceTest.php+27Now let's run the test to verify:Command dockerdoste/ nkt sdovkeeskneate/ep/rts/ASktimannyReportActivityServiceTest.php --no-coverageCould not open input file: /var/www/html/artisandocker exec docker_lamp_1 php /app/artisantests/Unit/Services/Kiosk/testedReports/AskJiminnyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockel• docker exec docker lamp 1 bash -c "cd /var/www && php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisancommand dockelo docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"Itlle win changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams11O:24uir-o( 4 spaces...
|
NULL
|
-1721715682181738533
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]v _ ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.php© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php X<?php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrdeclare(strict_types=1);C DeallnsightsPeriodFilter(e TrackProvidernstallled-vent.ono0 DealinsidnisPeriodrilteng FilterDetinition.php© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny \Component\ActivitySearch\Service;c rterverntoncolectousec rterverntoncuev.on© FilterDefinitionQueryColclass ActivitySearch© AutomatedReportResult.php• FilteredValueContainerli© IntMinMaxRange.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php[ AiActivityTypeclass Automacedкeрortskepo o:B15 X4 ^7 usagesprivate Container $container;[ AiAutomationD AiCallScoringpublic function __construct(Container $container){.}* Oreturn AutomatedReportD AskAnythingD AskJiminnyAipublic function getOnDemandPageFilters(): FilterDefinitionCollectionf...}DAWS• BillingManagementCache• CoachingFeedback> D CountryD CustomerApi35373839• DatabaseC DatadogC DateTimeDeallnsights• Dealkisks> IEasuicsearchpublic function create(array $data): Automate106107/**-108* Find an automated report by UUID109110* @param string $uvid111112* Oreturn AutomatedReport|null113114public function findByUuid(string $uvid): ?Al]115return AutomatedReport: :where('uvid', Aut118public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):› D Eloquent> DEncoding9 usages1 usage> M Encryption117public function getArrayFilterKeys(User $consumer): arrayf...}DESpubLie tunction tinabytaurousdlstring eiaurul 136> D Faker1 usage• FeatureFlagsif (is_numeric($id0rUuid)) {return AutomatedReport:: find((int) $1]private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecO FFMpeg• FileSystemD GeckoD GongGuzzleHttp198return AutomatedReport: :where('uvid', Aut199200KeyPoints• Kiosk1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}M LanquageDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot_ MobileSettings| ModelNotiticationD Nudge> [ ParagraphBreakerM ParticipantSpeechPartitionedCookie12402* Retrieve all standard (non-ASk Liminay) al 232*oodrdl sarno osorccocumin233The column tl 234*Cearal string ssorcosrection the sort a1m235236* Oreturn Collection<AutomatedReport>237— 24412 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection f...}/**245— 2462471248public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}D PlaybackPageD PlaylistL07* Retrieve all ASK Lininny reports created k2601 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerWindsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)Support Daily • in 2h 52mAL AskJiminny ReportActivityServiceT...Defaults100% C•Tue 14 Apr 12:08:42+D ...CascadeFixing ReportControllerAutomated Report Mar• Fixing Ask Jiminny RRoot Cause FoundThe buildRequestParamsFromSearch method in AskJiminnyReportActivityService passes sequence _number=0 implicitly (not in params), which meansisFirstRequest( returns true.When sequence_number is not in requestParams, the Criteria:: CreateFromkequest defaults it to 0, and isFirstRequest() returns true when empty I1sequenceNumber === 0.The frontend URL has sequence number=4— meaning it's not a first request. The service doesn't set it, so the criteria thinks it's a first request.Wnen 1srirstrequest = true.nese mollicttites are adalled tnar aren un tne saveo searehs" Acuvltylurar lonkande — aooles min curation = 1 lINAL MIN - tIters ourO-secono callls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-only3. OrganiserGroupIn - applies user's default group filterBut the frontend with sequence_number=4 skips all of these defaults, so it returns more results.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitdefaults don't apolv. Or alternatively, alwavs pass a non-zero sequence number in the merge in getAct.ivitvIdsForSavedSearch.Read AskJiminnyReportActivityService.php #L44-93Now let me verify my understanding of isFirstRequest:Reao crierla,onoConfirmed. The fix is clear and minimal. The getAivityIdsForSavedSearch method needs to pass sequence_number with a non-zero value so that isFirstRequest () returns false and no implicit defaults are applied.• AskJiminnyReportActivityService.php+I-1Now let me check if there's an existing test for AskJiminnyReportActivityService to update:ExploredAskJiminnvReoortActivtvServicelest.onv and searchedAsk.iminnvReoortActivitvI need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:• AskJiminnyReportActivityServiceTest.php+27Now let's run the test to verify:Command dockerdoste/ nkt sdovkeeskneate/ep/rts/ASktimannyReportActivityServiceTest.php --no-coverageCould not open input file: /var/www/html/artisandocker exec docker_lamp_1 php /app/artisantests/Unit/Services/Kiosk/testedReports/AskJiminnyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockel• docker exec docker lamp 1 bash -c "cd /var/www && php artisan testtests/Unit/Services/Kiosk/AutomatedReports/AskJiminnyReportActivityServiceTest.php --no-coverage 2>&1"Could not open input file: artisancommand dockelo docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"Itlle win changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams11O:24uir-o( 4 spaces...
|
NULL
|
|
11022
|
219
|
0
|
2026-04-14T09:08:57.582059+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157737582_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivitySearch.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Rerun 'PHPUnit: AskJiminnyReportActivityServiceTest.testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Stop 'AskJiminnyReportActivityServiceTest.testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults'
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
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...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Rerun 'PHPUnit: AskJiminnyReportActivityServiceTest.testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Stop 'AskJiminnyReportActivityServiceTest.testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.940625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\Service;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\AiCallScoreFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\AutoScoreFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ClosedDealsFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealCloseDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\HasTopicTriggersFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\PlaybackTopicFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictActivityChannel;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictPublicActivitiesOnly;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictTeam;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictUserActive;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictUserGroupScope;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\TeamInsights\\TopicFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Repositories\\Crm\\LayoutRepository;\nuse Jiminny\\Services\\TeamService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\n\nclass ActivitySearch\n{\n private Container $container;\n\n public function __construct(Container $container)\n {\n $this->container = $container;\n }\n\n public function getOnDemandPageFilters(): FilterDefinitionCollection\n {\n return FilterDefinitionCollection::make(\n Collection::make([\n // special case filters\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\ActivityUpdatedDate::class,\n FilterDefinition\\ActivityRecordingStopped::class,\n FilterDefinition\\ActivityFilter::class,\n FilterDefinition\\ExternalId::class,\n FilterDefinition\\NudgeRunId::class,\n FilterDefinition\\ParticipantUserIn::class,\n FilterDefinition\\PartnerFilterDefinition::class,\n\n // healthy restrictions\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictUserActive::class,\n FilterDefinition\\Security\\PrivateMeetingsForCurrentUserOnly::class,\n\n // regular filters\n FilterDefinition\\ActivityActualDate::class,\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\ActivityDurationRange::class,\n FilterDefinition\\ActivityPlaylistIn::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\ActivityRecorded::class,\n FilterDefinition\\ActivityType::class,\n FilterDefinition\\CoachingFeedbackAverageScore::class,\n AutoScoreFilter::class,\n AiCallScoreFilter::class,\n FilterDefinition\\CoachingFeedbackCoachUserIn::class,\n FilterDefinition\\CrmFieldCollection::class,\n FilterDefinition\\CurrentStage::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\CustomerMonologueDuration::class,\n FilterDefinition\\CustomerQuestionCount::class,\n FilterDefinition\\DealAge::class,\n DealCloseDate::class,\n FilterDefinition\\DealValue::class,\n FilterDefinition\\EngagingQuestionCount::class,\n FilterDefinition\\ShowInternalExternalActivitiesFilter::class,\n FilterDefinition\\HasTranscription::class,\n FilterDefinition\\InsightfulQuestionCount::class,\n FilterDefinition\\LanguageFilterDefinition::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\OrganiserGroupIn::class,\n FilterDefinition\\OrganiserUserIn::class,\n FilterDefinition\\PatienceRange::class,\n PlaybackTopicFilterDefinition::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\SpeechRate::class,\n FilterDefinition\\StageAtCallFilterDefinition::class,\n FilterDefinition\\TalkTimeRatio::class,\n FilterDefinition\\TeamMemberUserIn::class,\n FilterDefinition\\TranscriptionComposite::class,\n FilterDefinition\\UserMonologueDuration::class,\n FilterDefinition\\UserQuestionCount::class,\n FilterDefinition\\CommentCountRange::class,\n FilterDefinition\\HasPendingAiCrmNotes::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getOnDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection\n {\n return $this\n ->getOnDemandPageFilters()\n ->withCriteria($criteria)\n ->withConsumer($consumer)\n ->withRestrictions($consumer->getTeam());\n }\n\n /**\n * @return string[]\n */\n public function getArrayFilterKeys(User $consumer): array\n {\n return $this\n ->getOnDemandPageFilters()\n ->withConsumer($consumer)\n ->getPropertyTypes([FilterDefinitionCollection::PROPERTY_TYPE_ARRAY])\n ->keys()\n ->filter(static fn (string $key): bool => ! str_contains($key, '.'))\n ->values()\n ->all();\n }\n\n private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollection\n {\n $dateRangeFilterClass = $isExport\n ? FilterDefinition\\TeamInsights\\ConversationExport\\DateRangeFilter::class\n : FilterDefinition\\TeamInsights\\DateRangeFilter::class;\n\n return FilterDefinitionCollection::make(\n Collection::make([\n // special cases\n $dateRangeFilterClass,\n FilterDefinition\\TeamInsights\\Exists::class,\n\n // healthy restrictions\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictPublicActivitiesOnly::class,\n RestrictUserActive::class,\n\n // regular filters\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\TeamInsights\\ActivityDurationRange::class,\n FilterDefinition\\ActivityPlaylistIn::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\TeamInsights\\ActivityRecorded::class,\n FilterDefinition\\ActivityType::class,\n FilterDefinition\\CoachingFeedbackAverageScore::class,\n AutoScoreFilter::class,\n AiCallScoreFilter::class,\n FilterDefinition\\CoachingFeedbackCoachUserIn::class,\n FilterDefinition\\CrmFieldCollection::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\CurrentStage::class,\n FilterDefinition\\CustomerMonologueDuration::class,\n FilterDefinition\\CustomerQuestionCount::class,\n FilterDefinition\\DealAge::class,\n DealCloseDate::class,\n FilterDefinition\\DealValue::class,\n FilterDefinition\\EngagingQuestionCount::class,\n FilterDefinition\\ShowInternalExternalActivitiesFilter::class,\n FilterDefinition\\InsightfulQuestionCount::class,\n FilterDefinition\\LanguageFilterDefinition::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\TeamInsights\\UserInFilter::class,\n FilterDefinition\\TeamInsights\\UserGroupInFilter::class,\n FilterDefinition\\PatienceRange::class,\n PlaybackTopicFilterDefinition::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\SpeechRate::class,\n FilterDefinition\\StageAtCallFilterDefinition::class,\n FilterDefinition\\TalkTimeRatio::class,\n FilterDefinition\\TeamMemberUserIn::class,\n FilterDefinition\\TranscriptionComposite::class,\n FilterDefinition\\UserMonologueDuration::class,\n FilterDefinition\\UserQuestionCount::class,\n FilterDefinition\\CommentCountRange::class,\n // Relevant for topics in deals.\n ClosedDealsFilter::class,\n HasTopicTriggersFilterDefinition::class,\n TopicFilterDefinition::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n private function getDealInsightsPageFilters(\n bool $useCreatedDate = false,\n bool $includeDealType = false,\n bool $includePipeline = false,\n ): FilterDefinitionCollection {\n if ($useCreatedDate) {\n $periodFilterClass = FilterDefinition\\DealInsights\\CreatedPeriodFilter::class;\n } else {\n $periodFilterClass = FilterDefinition\\DealInsights\\ClosingPeriodFilter::class;\n }\n\n $filterSet = [\n RestrictTeam::class,\n $periodFilterClass,\n FilterDefinition\\DealInsights\\UserInFilter::class,\n FilterDefinition\\DealInsights\\UserGroupInFilter::class,\n FilterDefinition\\DealInsights\\DealStageInFilter::class,\n FilterDefinition\\DealInsights\\DealNameFilter::class,\n ];\n\n if ($includePipeline) {\n $filterSet[] = FilterDefinition\\DealInsights\\DealPipelineInFilter::class;\n }\n\n if ($includeDealType) {\n $filterSet[] = FilterDefinition\\DealInsights\\DealTypeInFilter::class;\n }\n\n return FilterDefinitionCollection::make(\n Collection::make($filterSet)\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getTeamInsightsPageFilterSet(\n Criteria $criteria,\n User $consumer,\n bool $isExport = false\n ): FilterDefinitionCollection {\n return $this\n ->getTeamInsightsPageFilters($isExport)\n ->withCriteria($criteria)\n ->withConsumer($consumer)\n ->withRestrictions($consumer->getTeam());\n }\n\n public function getDealInsightsPageFilterSet(\n Criteria $criteria,\n User $consumer\n ): FilterDefinitionCollection {\n $includeDealType = $this->shouldIncludeDealType($consumer);\n $includePipeline = $this->shouldIncludePipeline($consumer);\n $useCreatedDate = $this->shouldUseCreatedDate($consumer);\n\n return $this\n ->getDealInsightsPageFilters($useCreatedDate, $includeDealType, $includePipeline)\n ->withCriteria($criteria)\n ->withConsumer($consumer);\n }\n\n public function getTeamAiAutomationFilterSet(\n Criteria $criteria,\n User $consumer\n ): FilterDefinitionCollection {\n return $this\n ->getTeamAiAutomationPageFilterSet()\n ->withCriteria($criteria)\n ->withConsumer($consumer);\n }\n\n private function getTeamAiAutomationPageFilterSet(): FilterDefinitionCollection\n {\n $filterSet = [\n RestrictTeam::class,\n FilterDefinition\\DealInsights\\DealStageInFilter::class,\n ];\n\n return FilterDefinitionCollection::make(\n Collection::make($filterSet)\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getHomepageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection\n {\n $filterDefinitionCollection = FilterDefinitionCollection::make(\n Collection::make([\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictUserActive::class,\n FilterDefinition\\Security\\PrivateMeetingsForCurrentUserOnly::class,\n FilterDefinition\\ActivityActualDate::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\ActivityDurationRange::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\ActivityRecorded::class,\n FilterDefinition\\ActivityRecordingStopped::class,\n FilterDefinition\\ActivityScheduledDate::class,\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\OrganiserUserIn::class,\n FilterDefinition\\OrganiserUserNotIn::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\UserGroupInOptionalFilter::class,\n FilterDefinition\\OnlyActiveUsers::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n $filterDefinitionCollection->withCriteria($criteria);\n $filterDefinitionCollection->withConsumer($consumer);\n\n return $filterDefinitionCollection;\n }\n\n public function getPartnerFilterSet(Criteria $criteria): FilterDefinitionCollection\n {\n $filterDefinitionCollection = FilterDefinitionCollection::make(\n Collection::make([\n RestrictActivityChannel::class,\n FilterDefinition\\OrganiserTeamIn::class,\n FilterDefinition\\ActivityUpdatedDate::class,\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\SortBy::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all()\n );\n $filterDefinitionCollection->withCriteria($criteria);\n\n return $filterDefinitionCollection;\n }\n\n private function shouldIncludeDealType(User $user): bool\n {\n $crmConfig = $user->getTeam()->getCrmConfiguration();\n $crmProviderName = $crmConfig->getProviderName();\n\n if (! array_key_exists($crmProviderName, Field::BUSINESS_TYPE_FIELDS)) {\n return false;\n }\n\n $layoutRepository = app(LayoutRepository::class);\n $layoutFields = $layoutRepository->getDealInsightLayoutFields($crmConfig);\n $dealTypeField = Field::BUSINESS_TYPE_FIELDS[$crmProviderName];\n\n if (! in_array($dealTypeField, $layoutFields)) {\n return false;\n }\n\n return true;\n }\n\n private function shouldIncludePipeline(User $user): bool\n {\n $crmConfig = $user->getTeam()->getCrmConfiguration();\n $crmProviderName = $crmConfig->getProviderName();\n\n if (in_array($crmProviderName, [\n Configuration::PROVIDER_SALESFORCE,\n Configuration::PROVIDER_INTEGRATION_APP,\n ])) {\n return false;\n }\n\n return true;\n }\n\n private function shouldUseCreatedDate(User $user): bool\n {\n $teamService = app(TeamService::class);\n\n return ! $teamService->useDealInsightsClosedDateFilter($user->getTeam());\n }\n}","depth":4,"bounds":{"left":0.32617188,"top":0.10625,"width":0.34101564,"height":0.89375},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\Service;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\AiCallScoreFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\AutoScoreFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ClosedDealsFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealCloseDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\HasTopicTriggersFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\PlaybackTopicFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictActivityChannel;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictPublicActivitiesOnly;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictTeam;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictUserActive;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\Security\\RestrictUserGroupScope;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\TeamInsights\\TopicFilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Repositories\\Crm\\LayoutRepository;\nuse Jiminny\\Services\\TeamService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\n\nclass ActivitySearch\n{\n private Container $container;\n\n public function __construct(Container $container)\n {\n $this->container = $container;\n }\n\n public function getOnDemandPageFilters(): FilterDefinitionCollection\n {\n return FilterDefinitionCollection::make(\n Collection::make([\n // special case filters\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\ActivityUpdatedDate::class,\n FilterDefinition\\ActivityRecordingStopped::class,\n FilterDefinition\\ActivityFilter::class,\n FilterDefinition\\ExternalId::class,\n FilterDefinition\\NudgeRunId::class,\n FilterDefinition\\ParticipantUserIn::class,\n FilterDefinition\\PartnerFilterDefinition::class,\n\n // healthy restrictions\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictUserActive::class,\n FilterDefinition\\Security\\PrivateMeetingsForCurrentUserOnly::class,\n\n // regular filters\n FilterDefinition\\ActivityActualDate::class,\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\ActivityDurationRange::class,\n FilterDefinition\\ActivityPlaylistIn::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\ActivityRecorded::class,\n FilterDefinition\\ActivityType::class,\n FilterDefinition\\CoachingFeedbackAverageScore::class,\n AutoScoreFilter::class,\n AiCallScoreFilter::class,\n FilterDefinition\\CoachingFeedbackCoachUserIn::class,\n FilterDefinition\\CrmFieldCollection::class,\n FilterDefinition\\CurrentStage::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\CustomerMonologueDuration::class,\n FilterDefinition\\CustomerQuestionCount::class,\n FilterDefinition\\DealAge::class,\n DealCloseDate::class,\n FilterDefinition\\DealValue::class,\n FilterDefinition\\EngagingQuestionCount::class,\n FilterDefinition\\ShowInternalExternalActivitiesFilter::class,\n FilterDefinition\\HasTranscription::class,\n FilterDefinition\\InsightfulQuestionCount::class,\n FilterDefinition\\LanguageFilterDefinition::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\OrganiserGroupIn::class,\n FilterDefinition\\OrganiserUserIn::class,\n FilterDefinition\\PatienceRange::class,\n PlaybackTopicFilterDefinition::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\SpeechRate::class,\n FilterDefinition\\StageAtCallFilterDefinition::class,\n FilterDefinition\\TalkTimeRatio::class,\n FilterDefinition\\TeamMemberUserIn::class,\n FilterDefinition\\TranscriptionComposite::class,\n FilterDefinition\\UserMonologueDuration::class,\n FilterDefinition\\UserQuestionCount::class,\n FilterDefinition\\CommentCountRange::class,\n FilterDefinition\\HasPendingAiCrmNotes::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getOnDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection\n {\n return $this\n ->getOnDemandPageFilters()\n ->withCriteria($criteria)\n ->withConsumer($consumer)\n ->withRestrictions($consumer->getTeam());\n }\n\n /**\n * @return string[]\n */\n public function getArrayFilterKeys(User $consumer): array\n {\n return $this\n ->getOnDemandPageFilters()\n ->withConsumer($consumer)\n ->getPropertyTypes([FilterDefinitionCollection::PROPERTY_TYPE_ARRAY])\n ->keys()\n ->filter(static fn (string $key): bool => ! str_contains($key, '.'))\n ->values()\n ->all();\n }\n\n private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollection\n {\n $dateRangeFilterClass = $isExport\n ? FilterDefinition\\TeamInsights\\ConversationExport\\DateRangeFilter::class\n : FilterDefinition\\TeamInsights\\DateRangeFilter::class;\n\n return FilterDefinitionCollection::make(\n Collection::make([\n // special cases\n $dateRangeFilterClass,\n FilterDefinition\\TeamInsights\\Exists::class,\n\n // healthy restrictions\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictPublicActivitiesOnly::class,\n RestrictUserActive::class,\n\n // regular filters\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\TeamInsights\\ActivityDurationRange::class,\n FilterDefinition\\ActivityPlaylistIn::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\TeamInsights\\ActivityRecorded::class,\n FilterDefinition\\ActivityType::class,\n FilterDefinition\\CoachingFeedbackAverageScore::class,\n AutoScoreFilter::class,\n AiCallScoreFilter::class,\n FilterDefinition\\CoachingFeedbackCoachUserIn::class,\n FilterDefinition\\CrmFieldCollection::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\CurrentStage::class,\n FilterDefinition\\CustomerMonologueDuration::class,\n FilterDefinition\\CustomerQuestionCount::class,\n FilterDefinition\\DealAge::class,\n DealCloseDate::class,\n FilterDefinition\\DealValue::class,\n FilterDefinition\\EngagingQuestionCount::class,\n FilterDefinition\\ShowInternalExternalActivitiesFilter::class,\n FilterDefinition\\InsightfulQuestionCount::class,\n FilterDefinition\\LanguageFilterDefinition::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\TeamInsights\\UserInFilter::class,\n FilterDefinition\\TeamInsights\\UserGroupInFilter::class,\n FilterDefinition\\PatienceRange::class,\n PlaybackTopicFilterDefinition::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\SpeechRate::class,\n FilterDefinition\\StageAtCallFilterDefinition::class,\n FilterDefinition\\TalkTimeRatio::class,\n FilterDefinition\\TeamMemberUserIn::class,\n FilterDefinition\\TranscriptionComposite::class,\n FilterDefinition\\UserMonologueDuration::class,\n FilterDefinition\\UserQuestionCount::class,\n FilterDefinition\\CommentCountRange::class,\n // Relevant for topics in deals.\n ClosedDealsFilter::class,\n HasTopicTriggersFilterDefinition::class,\n TopicFilterDefinition::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n private function getDealInsightsPageFilters(\n bool $useCreatedDate = false,\n bool $includeDealType = false,\n bool $includePipeline = false,\n ): FilterDefinitionCollection {\n if ($useCreatedDate) {\n $periodFilterClass = FilterDefinition\\DealInsights\\CreatedPeriodFilter::class;\n } else {\n $periodFilterClass = FilterDefinition\\DealInsights\\ClosingPeriodFilter::class;\n }\n\n $filterSet = [\n RestrictTeam::class,\n $periodFilterClass,\n FilterDefinition\\DealInsights\\UserInFilter::class,\n FilterDefinition\\DealInsights\\UserGroupInFilter::class,\n FilterDefinition\\DealInsights\\DealStageInFilter::class,\n FilterDefinition\\DealInsights\\DealNameFilter::class,\n ];\n\n if ($includePipeline) {\n $filterSet[] = FilterDefinition\\DealInsights\\DealPipelineInFilter::class;\n }\n\n if ($includeDealType) {\n $filterSet[] = FilterDefinition\\DealInsights\\DealTypeInFilter::class;\n }\n\n return FilterDefinitionCollection::make(\n Collection::make($filterSet)\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getTeamInsightsPageFilterSet(\n Criteria $criteria,\n User $consumer,\n bool $isExport = false\n ): FilterDefinitionCollection {\n return $this\n ->getTeamInsightsPageFilters($isExport)\n ->withCriteria($criteria)\n ->withConsumer($consumer)\n ->withRestrictions($consumer->getTeam());\n }\n\n public function getDealInsightsPageFilterSet(\n Criteria $criteria,\n User $consumer\n ): FilterDefinitionCollection {\n $includeDealType = $this->shouldIncludeDealType($consumer);\n $includePipeline = $this->shouldIncludePipeline($consumer);\n $useCreatedDate = $this->shouldUseCreatedDate($consumer);\n\n return $this\n ->getDealInsightsPageFilters($useCreatedDate, $includeDealType, $includePipeline)\n ->withCriteria($criteria)\n ->withConsumer($consumer);\n }\n\n public function getTeamAiAutomationFilterSet(\n Criteria $criteria,\n User $consumer\n ): FilterDefinitionCollection {\n return $this\n ->getTeamAiAutomationPageFilterSet()\n ->withCriteria($criteria)\n ->withConsumer($consumer);\n }\n\n private function getTeamAiAutomationPageFilterSet(): FilterDefinitionCollection\n {\n $filterSet = [\n RestrictTeam::class,\n FilterDefinition\\DealInsights\\DealStageInFilter::class,\n ];\n\n return FilterDefinitionCollection::make(\n Collection::make($filterSet)\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n }\n\n public function getHomepageFilterSet(Criteria $criteria, User $consumer): FilterDefinitionCollection\n {\n $filterDefinitionCollection = FilterDefinitionCollection::make(\n Collection::make([\n RestrictTeam::class,\n RestrictUserGroupScope::class,\n RestrictActivityChannel::class,\n RestrictUserActive::class,\n FilterDefinition\\Security\\PrivateMeetingsForCurrentUserOnly::class,\n FilterDefinition\\ActivityActualDate::class,\n FilterDefinition\\Customer::class,\n FilterDefinition\\ActivityChannel::class,\n FilterDefinition\\ActivityDurationRange::class,\n FilterDefinition\\ActivityProviderIn::class,\n FilterDefinition\\ActivityRecorded::class,\n FilterDefinition\\ActivityRecordingStopped::class,\n FilterDefinition\\ActivityScheduledDate::class,\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\LoggedToCrm::class,\n FilterDefinition\\OrganiserUserIn::class,\n FilterDefinition\\OrganiserUserNotIn::class,\n FilterDefinition\\ProviderFilterDefinition::class,\n FilterDefinition\\SortBy::class,\n FilterDefinition\\UserGroupInOptionalFilter::class,\n FilterDefinition\\OnlyActiveUsers::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all(),\n );\n $filterDefinitionCollection->withCriteria($criteria);\n $filterDefinitionCollection->withConsumer($consumer);\n\n return $filterDefinitionCollection;\n }\n\n public function getPartnerFilterSet(Criteria $criteria): FilterDefinitionCollection\n {\n $filterDefinitionCollection = FilterDefinitionCollection::make(\n Collection::make([\n RestrictActivityChannel::class,\n FilterDefinition\\OrganiserTeamIn::class,\n FilterDefinition\\ActivityUpdatedDate::class,\n FilterDefinition\\ActivityStatusIn::class,\n FilterDefinition\\SortBy::class,\n ])\n ->map(fn (string $className): FilterDefinition => $this->container->make($className))\n ->all()\n );\n $filterDefinitionCollection->withCriteria($criteria);\n\n return $filterDefinitionCollection;\n }\n\n private function shouldIncludeDealType(User $user): bool\n {\n $crmConfig = $user->getTeam()->getCrmConfiguration();\n $crmProviderName = $crmConfig->getProviderName();\n\n if (! array_key_exists($crmProviderName, Field::BUSINESS_TYPE_FIELDS)) {\n return false;\n }\n\n $layoutRepository = app(LayoutRepository::class);\n $layoutFields = $layoutRepository->getDealInsightLayoutFields($crmConfig);\n $dealTypeField = Field::BUSINESS_TYPE_FIELDS[$crmProviderName];\n\n if (! in_array($dealTypeField, $layoutFields)) {\n return false;\n }\n\n return true;\n }\n\n private function shouldIncludePipeline(User $user): bool\n {\n $crmConfig = $user->getTeam()->getCrmConfiguration();\n $crmProviderName = $crmConfig->getProviderName();\n\n if (in_array($crmProviderName, [\n Configuration::PROVIDER_SALESFORCE,\n Configuration::PROVIDER_INTEGRATION_APP,\n ])) {\n return false;\n }\n\n return true;\n }\n\n private function shouldUseCreatedDate(User $user): bool\n {\n $teamService = app(TeamService::class);\n\n return ! $teamService->useDealInsightsClosedDateFilter($user->getTeam());\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"bounds":{"left":0.15234375,"top":0.084027775,"width":0.39882812,"height":0.91597223},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"bounds":{"left":0.03203125,"top":0.0,"width":0.01875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"bounds":{"left":0.039453126,"top":0.0,"width":0.027734375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"bounds":{"left":0.039453126,"top":0.0,"width":0.0375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Acl, folder","depth":9,"bounds":{"left":0.046875,"top":0.0,"width":0.0171875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"bounds":{"left":0.046875,"top":0.0,"width":0.03828125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"bounds":{"left":0.046875,"top":0.0,"width":0.027734375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics, folder","depth":9,"bounds":{"left":0.046875,"top":0.0020833334,"width":0.049609374,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch, folder","depth":9,"bounds":{"left":0.046875,"top":0.017361112,"width":0.04453125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"EventSubscriber, folder","depth":10,"bounds":{"left":0.054296874,"top":0.03263889,"width":0.04921875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinition, folder","depth":10,"bounds":{"left":0.054296874,"top":0.047916666,"width":0.04453125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Service","depth":10,"bounds":{"left":0.054296874,"top":0.063194446,"width":0.02734375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ActivityApiSearch.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.07847222,"width":0.06289063,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.09375,"width":0.055078126,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"UserOptionsByGroup.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.10902778,"width":0.07109375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AbstractStageFilterDefinition.php, abstract class","depth":10,"bounds":{"left":0.054296874,"top":0.124305554,"width":0.08945312,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearchServiceProvider.php, final class","depth":10,"bounds":{"left":0.054296874,"top":0.13958333,"width":0.09296875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsPeriodFilterFactory.php","depth":10,"bounds":{"left":0.054296874,"top":0.15486111,"width":0.0953125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsPeriodFilterFactoryInterface.php, interface","depth":10,"bounds":{"left":0.054296874,"top":0.1701389,"width":0.11679687,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinition.php, abstract class","depth":10,"bounds":{"left":0.054296874,"top":0.18541667,"width":0.055078126,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionCollection.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.20069444,"width":0.07890625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionQuery.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.21597221,"width":0.06953125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionQueryCollection.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.23125,"width":0.09375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FilteredValueContainerInterface.php, interface","depth":10,"bounds":{"left":0.054296874,"top":0.24652778,"width":0.096875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"IntMinMaxRange.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.26180556,"width":0.06015625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"bounds":{"left":0.046875,"top":0.27708334,"width":0.04453125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"bounds":{"left":0.046875,"top":0.2923611,"width":0.041796874,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"bounds":{"left":0.046875,"top":0.30763888,"width":0.04140625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"bounds":{"left":0.046875,"top":0.32291666,"width":0.03984375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"bounds":{"left":0.046875,"top":0.33819443,"width":0.04140625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"bounds":{"left":0.046875,"top":0.35347223,"width":0.02109375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"bounds":{"left":0.046875,"top":0.36875,"width":0.055078126,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"bounds":{"left":0.046875,"top":0.38402778,"width":0.025,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"bounds":{"left":0.046875,"top":0.39930555,"width":0.055859376,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"bounds":{"left":0.046875,"top":0.41458333,"width":0.02890625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"bounds":{"left":0.046875,"top":0.4298611,"width":0.040625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"bounds":{"left":0.046875,"top":0.4451389,"width":0.032421876,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"bounds":{"left":0.046875,"top":0.46041667,"width":0.030078124,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"bounds":{"left":0.046875,"top":0.47569445,"width":0.0328125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"bounds":{"left":0.046875,"top":0.49097222,"width":0.0390625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"bounds":{"left":0.046875,"top":0.50625,"width":0.0328125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"bounds":{"left":0.046875,"top":0.52152777,"width":0.0421875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"bounds":{"left":0.046875,"top":0.53680557,"width":0.03046875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"bounds":{"left":0.046875,"top":0.5520833,"width":0.03203125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"bounds":{"left":0.046875,"top":0.5673611,"width":0.03515625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"bounds":{"left":0.046875,"top":0.58263886,"width":0.016015625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"bounds":{"left":0.046875,"top":0.59791666,"width":0.023046875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"bounds":{"left":0.046875,"top":0.61319447,"width":0.040625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"bounds":{"left":0.046875,"top":0.6284722,"width":0.029296875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"bounds":{"left":0.046875,"top":0.64375,"width":0.0359375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"bounds":{"left":0.046875,"top":0.65902776,"width":0.025,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"bounds":{"left":0.046875,"top":0.67430556,"width":0.022265624,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"bounds":{"left":0.046875,"top":0.68958336,"width":0.036328126,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"bounds":{"left":0.046875,"top":0.7048611,"width":0.03359375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"bounds":{"left":0.046875,"top":0.7201389,"width":0.02265625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"bounds":{"left":0.046875,"top":0.73541665,"width":0.056640625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"bounds":{"left":0.046875,"top":0.75069445,"width":0.031640626,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"bounds":{"left":0.046875,"top":0.7659722,"width":0.023828125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"bounds":{"left":0.046875,"top":0.78125,"width":0.021875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"bounds":{"left":0.046875,"top":0.7965278,"width":0.04296875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"bounds":{"left":0.046875,"top":0.81180555,"width":0.037109375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"bounds":{"left":0.046875,"top":0.82708335,"width":0.0453125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Model","depth":9,"bounds":{"left":0.046875,"top":0.8423611,"width":0.024609376,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Notification","depth":9,"bounds":{"left":0.046875,"top":0.8576389,"width":0.037109375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Nudge","depth":9,"bounds":{"left":0.046875,"top":0.87291664,"width":0.025390625,"height":0.015277778},"role_description":"text"}]...
|
-3507986962049824144
|
-3743354318684703676
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Rerun 'PHPUnit: AskJiminnyReportActivityServiceTest.testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Stop 'AskJiminnyReportActivityServiceTest.testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults'
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
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...
|
11021
|
|
11025
|
219
|
2
|
2026-04-14T09:09:01.854582+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157741854_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]v _ ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.php© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php X<?php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrdeclare(strict_types=1);C DeallnsightsPeriodFilter(e TrackProvidernstallled-vent.ono0 DealinsidnisPeriodrilteng FilterDetinition.php© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny \Component\ActivitySearch\Service;c rterverntoncolectousec rterverntoncuev.on© FilterDefinitionQueryColclass ActivitySearch© AutomatedReportResult.php• FilteredValueContainerli© IntMinMaxRange.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php[ AiActivityTypeclass Automacedкeрortskepo o:B15 X4 ^7 usagesprivate Container $container;[ AiAutomationD AiCallScoringpublic function __construct(Container $container){.}* Oreturn AutomatedReportD AskAnythingD AskJiminnyAipublic function getOnDemandPageFilters(): FilterDefinitionCollectionf...}DAWS• BillingManagementCache• CoachingFeedback> D CountryD CustomerApi35373839• DatabaseC DatadogC DateTimeDeallnsights• Dealkisks> IEasuicsearchpublic function create(array $data): Automate106107/**-108* Find an automated report by UUID109110* @param string $uvid111112* Oreturn AutomatedReport|null113114public function findByUuid(string $uvid): ?Al]115return AutomatedReport: :where('uvid', Aut118public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):› D Eloquent> DEncoding9 usages1 usage> M Encryption117public function getArrayFilterKeys(User $consumer): arrayf...}DESpubLie tunction tinabytaurousdlstring eiaurul 136> D Faker1 usage• FeatureFlagsif (is_numeric($id0rUuid)) {return AutomatedReport:: find((int) $1]private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecO FFMpeg• FileSystemD GeckoD GongGuzzleHttp198return AutomatedReport: :where('uvid', Aut199200KeyPoints• Kiosk1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}M LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot_ MobileSettings| ModelNotiticationD Nudge> [ ParagraphBreakerM ParticipantSpeechPartitionedCookie12402* Retrieve all standard (non-ASk Liminay) al 232*oodrdl sarno osorccocumin233The column tl 234*Cearal string ssorcosrection the sort a1m235236* Oreturn Collection<AutomatedReport>237— 24412 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection f...}/**245— 2462471248public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitioncollection ...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}D PlaybackPageD PlaylistL07* Retrieve all ASK Lininny reports created k2601 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerWindsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)j Support Daily • in 2h 51 mAL AskJiminnyReportActivityServiceT...Defaults100% C•Tue 14 Apr 12:09:01CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny R+D ..lne ronteno UxLhas sequence numbere4 - meanno s nor a list reduest. ne sevice doesh seut. so the cireda chnks s a listrequestWhen isFirstRequest() = true , these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-onlyOraaniserGroupIn - applies user's default group filterBut the frontend with sequence_number=4 skips all of these defaults, so it returns more results.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence_number in the merge in getActivityldsForSavedSearchRead AskJiminnyReportActivitySelce.ono #L44-93Now let me verify my understanding of isFirstRequest :Read criteria.onolConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch method needs to pass sequence_number with a non-zero value so that isFirstRequest() returns false and no imolicit defaults are apolied.ewAskJiminnyReportActivityService.php+1-11Now ler me check mtnere's anex sune estror AskyiminnvredortAcuvi vservice lo uocare.Explored AskJiminnyReportActivityServiceTest.php and searched AskJiminnyReportActivity*I need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:AskJiminnyReportActivityServicelest.pnpNow let's run the test to verify:commana dockelo decte/nke/ tockces/klosk/RuP /ar/ep/nts/AkJinanyReportActivityServacetest- php -no-coverageCould not open input file: /var/www/html/artisanCommand dockerdester ext/sdrvices/KLosk/Automate/kepirts/ASkJ iminnyReportActivityserviceTest.php --no-coverageCould not open input file: /app/artisanaocker exec aocker lamp 1 bash -c"cd /var/www && php artisan testLests/unte/services/ nlosk/ Aucomacearepores/ Askuemennyкeportactivilyservicelest.onp =-no-coverdge 22al"Could not open input file: artisanCommand docker• docker exec docker lamp 1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"home/iiminny/artisanartisan testdests/axec sdovkers/k2p 1/Autonae Reports/A5 kaimay yRportArtivatySesviceTest.php --no-coverage 2›61Itlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (X4L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allwinasur leams11O:24uir-o( 4 spaces...
|
NULL
|
4616817957594730042
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpToolsWindowHelpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]v _ ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php x© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.php© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php X<?php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrdeclare(strict_types=1);C DeallnsightsPeriodFilter(e TrackProvidernstallled-vent.ono0 DealinsidnisPeriodrilteng FilterDetinition.php© CreateActivityLoggedEvent.php(©) ActivityLogged.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.phpnamespace Jiminny \Component\ActivitySearch\Service;c rterverntoncolectousec rterverntoncuev.on© FilterDefinitionQueryColclass ActivitySearch© AutomatedReportResult.php• FilteredValueContainerli© IntMinMaxRange.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php[ AiActivityTypeclass Automacedкeрortskepo o:B15 X4 ^7 usagesprivate Container $container;[ AiAutomationD AiCallScoringpublic function __construct(Container $container){.}* Oreturn AutomatedReportD AskAnythingD AskJiminnyAipublic function getOnDemandPageFilters(): FilterDefinitionCollectionf...}DAWS• BillingManagementCache• CoachingFeedback> D CountryD CustomerApi35373839• DatabaseC DatadogC DateTimeDeallnsights• Dealkisks> IEasuicsearchpublic function create(array $data): Automate106107/**-108* Find an automated report by UUID109110* @param string $uvid111112* Oreturn AutomatedReport|null113114public function findByUuid(string $uvid): ?Al]115return AutomatedReport: :where('uvid', Aut118public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):› D Eloquent> DEncoding9 usages1 usage> M Encryption117public function getArrayFilterKeys(User $consumer): arrayf...}DESpubLie tunction tinabytaurousdlstring eiaurul 136> D Faker1 usage• FeatureFlagsif (is_numeric($id0rUuid)) {return AutomatedReport:: find((int) $1]private function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollecO FFMpeg• FileSystemD GeckoD GongGuzzleHttp198return AutomatedReport: :where('uvid', Aut199200KeyPoints• Kiosk1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}M LanquadeDetectionLiveFeedD Locks• Math• MediaPipeline• MeetingBot_ MobileSettings| ModelNotiticationD Nudge> [ ParagraphBreakerM ParticipantSpeechPartitionedCookie12402* Retrieve all standard (non-ASk Liminay) al 232*oodrdl sarno osorccocumin233The column tl 234*Cearal string ssorcosrection the sort a1m235236* Oreturn Collection<AutomatedReport>237— 24412 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection f...}/**245— 2462471248public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitioncollection ...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}D PlaybackPageD PlaylistL07* Retrieve all ASK Lininny reports created k2601 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerWindsurf changelog 2.12.21: A new version is available. // View Changelog (today 10:33)j Support Daily • in 2h 51 mAL AskJiminnyReportActivityServiceT...Defaults100% C•Tue 14 Apr 12:09:01CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny R+D ..lne ronteno UxLhas sequence numbere4 - meanno s nor a list reduest. ne sevice doesh seut. so the cireda chnks s a listrequestWhen isFirstRequest() = true , these implicit filters are applied that aren't in the saved search:1. ActivityDurationRange - applies min_duration = 1 (INITIAL_MIN) - filters out 0-second calls2. ActivityRecorded - applies only_recorded = 1 (DEFAULT_VALUE = OPTION_RECORDED) - filters to recorded-onlyOraaniserGroupIn - applies user's default group filterBut the frontend with sequence_number=4 skips all of these defaults, so it returns more results.The fix should be in buildRequestParamsFromSearch - it needs to pass sequence_number in the built params to signal "not a first request", so the implicitdefaults don't apply. Or alternatively, always pass a non-zero sequence_number in the merge in getActivityldsForSavedSearchRead AskJiminnyReportActivitySelce.ono #L44-93Now let me verify my understanding of isFirstRequest :Read criteria.onolConfirmed. The fix is clear and minimal. The getActivityIdsForSavedSearch method needs to pass sequence_number with a non-zero value so that isFirstRequest() returns false and no imolicit defaults are apolied.ewAskJiminnyReportActivityService.php+1-11Now ler me check mtnere's anex sune estror AskyiminnvredortAcuvi vservice lo uocare.Explored AskJiminnyReportActivityServiceTest.php and searched AskJiminnyReportActivity*I need to add a test that verifies sequence_number=1 is passed to Criteria (so isFirstRequest() returns false ). Let me add it to the existing test file:AskJiminnyReportActivityServicelest.pnpNow let's run the test to verify:commana dockelo decte/nke/ tockces/klosk/RuP /ar/ep/nts/AkJinanyReportActivityServacetest- php -no-coverageCould not open input file: /var/www/html/artisanCommand dockerdester ext/sdrvices/KLosk/Automate/kepirts/ASkJ iminnyReportActivityserviceTest.php --no-coverageCould not open input file: /app/artisanaocker exec aocker lamp 1 bash -c"cd /var/www && php artisan testLests/unte/services/ nlosk/ Aucomacearepores/ Askuemennyкeportactivilyservicelest.onp =-no-coverdge 22al"Could not open input file: artisanCommand docker• docker exec docker lamp 1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"home/iiminny/artisanartisan testdests/axec sdovkers/k2p 1/Autonae Reports/A5 kaimay yRportArtivatySesviceTest.php --no-coverage 2›61Itlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (X4L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allwinasur leams11O:24uir-o( 4 spaces...
|
11024
|
|
11036
|
219
|
7
|
2026-04-14T09:09:50.100242+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157790100_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodelaravelRetactonToo PhpStormFileFditViewNavigateCodelaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ActivityTypeService.(©) AskJiminnyReportAc© AutomatedReportse© AutomatedReportss© DealStagesService.pC) RecipientsService.ph€ ReportSort. php€ ReportSortDirection.(©) KioskService.php> _ MailMeetingGenerator_ NotificationD 0Auth2RecallAl_ security>_ Strategy07 Streaming>MTeam> M Telephonv› _ UserPilotWebhookFindvecurences or isrirstkeouestTargets(©) ReportController.phpJiminnybeouecommana.ong= custom.log= laravel.loge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php4 console [EUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.pnp© AutomatedReportsSendCommand.php© AddLayoutentities.php© Criteria.php >© AskJiminnyReportActivityServiceTest.phpCi RequestGenerateAskJiminnyReportJobTest.phpC) Team.onp(©) AutomatedReportsRepository.php XO-isFirstRequestX 3 Cc W *T.YA© AutomatedReportsService.phpC CreateHeldActivityEvent.phpclass criteria41A46 MS^© TrackProviderInstalledEvent.php1261c) CreateActivityLoggeacvenconpC UserPilotActivityListener.php1204public function getLimito: intf...h(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php12001267public function isEmptyo: bool...hC RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php1L/112721276public function isFirstRequestO: boolk...h(C) AutomatedReport.php1277public function getonLyActiveUsers: boolt...hclass Automacedкeрortskepo o:B15 X4 Av 12811284#1283/*** Porse a wedt Instonts dote tron reduest deroures, nonduno nutdenory values drdcet* Inis mechod is specifically for beal insights date flelas to support the "ALl time" fi* Retrieve all standard (non-Ask Jiminny) m-2os11280x ooaran coccecmon meceroures* dparam string ssortcolumnThe column 1287* Anaram ctnina Sconthinection The cont dinc 1288* oparam scrine okeu*opara vaceicwecone occllecone• Occurrences of "isFirstRequest' in File 'Criteria.phpFound occurrences in File 'Criteria.php' 1 result>nclassiried result40lobla Support Daily • in 2h 51 m100% [AskJiminnyReportActivityServiceT...Defaults vTue 14 Apr 12:09:49CascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny RepNow let's run the test to verifvCommand dockerltesterunxt/ drvkee-/Kosk/Autonatedeports/AartinanyReportActivityserviceTest.php -n-coverageloul nor oen nolt tler var w nunwarusanCommand dockeldocker_docker exec docker- Lamp_1 php /app/artisarredkenorts/ask.lminnvrenortactiv1tv.ervicelest.ohn =-no-coveradeCould not open input file: /app/artisarCommand dockerItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (&+L)+ <> Code Claude Sonnet 4.6wView allReject allAccept allOUT›‹ <›Select item to previewlests passed: (moments agoW Windsurf Teams 1272:35 (14 chars)UTF-8ia 4 spaces...
|
NULL
|
1605497110261020743
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodelaravelRetactonToo PhpStormFileFditViewNavigateCodelaravelRetactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ActivityTypeService.(©) AskJiminnyReportAc© AutomatedReportse© AutomatedReportss© DealStagesService.pC) RecipientsService.ph€ ReportSort. php€ ReportSortDirection.(©) KioskService.php> _ MailMeetingGenerator_ NotificationD 0Auth2RecallAl_ security>_ Strategy07 Streaming>MTeam> M Telephonv› _ UserPilotWebhookFindvecurences or isrirstkeouestTargets(©) ReportController.phpJiminnybeouecommana.ong= custom.log= laravel.loge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php4 console [EUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.pnp© AutomatedReportsSendCommand.php© AddLayoutentities.php© Criteria.php >© AskJiminnyReportActivityServiceTest.phpCi RequestGenerateAskJiminnyReportJobTest.phpC) Team.onp(©) AutomatedReportsRepository.php XO-isFirstRequestX 3 Cc W *T.YA© AutomatedReportsService.phpC CreateHeldActivityEvent.phpclass criteria41A46 MS^© TrackProviderInstalledEvent.php1261c) CreateActivityLoggeacvenconpC UserPilotActivityListener.php1204public function getLimito: intf...h(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php12001267public function isEmptyo: bool...hC RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php1L/112721276public function isFirstRequestO: boolk...h(C) AutomatedReport.php1277public function getonLyActiveUsers: boolt...hclass Automacedкeрortskepo o:B15 X4 Av 12811284#1283/*** Porse a wedt Instonts dote tron reduest deroures, nonduno nutdenory values drdcet* Inis mechod is specifically for beal insights date flelas to support the "ALl time" fi* Retrieve all standard (non-Ask Jiminny) m-2os11280x ooaran coccecmon meceroures* dparam string ssortcolumnThe column 1287* Anaram ctnina Sconthinection The cont dinc 1288* oparam scrine okeu*opara vaceicwecone occllecone• Occurrences of "isFirstRequest' in File 'Criteria.phpFound occurrences in File 'Criteria.php' 1 result>nclassiried result40lobla Support Daily • in 2h 51 m100% [AskJiminnyReportActivityServiceT...Defaults vTue 14 Apr 12:09:49CascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny RepNow let's run the test to verifvCommand dockerltesterunxt/ drvkee-/Kosk/Autonatedeports/AartinanyReportActivityserviceTest.php -n-coverageloul nor oen nolt tler var w nunwarusanCommand dockeldocker_docker exec docker- Lamp_1 php /app/artisarredkenorts/ask.lminnvrenortactiv1tv.ervicelest.ohn =-no-coveradeCould not open input file: /app/artisarCommand dockerItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (&+L)+ <> Code Claude Sonnet 4.6wView allReject allAccept allOUT›‹ <›Select item to previewlests passed: (moments agoW Windsurf Teams 1272:35 (14 chars)UTF-8ia 4 spaces...
|
NULL
|
|
11043
|
219
|
11
|
2026-04-14T09:09:57.677781+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157797677_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
NULL
|
NULL
|
NULL
|
NULL
|
visual_change
|
NULL
|
NULL
|
NULL
|
NULL
|
|
11048
|
219
|
14
|
2026-04-14T09:10:03.728863+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157803728_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
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
|
-7355129271701132715
|
NULL
|
visual_change
|
ocr
|
NULL
|
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:...
|
11047
|
|
11055
|
219
|
18
|
2026-04-14T09:10:17.905774+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157817905_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-249341903282119781
|
-8276470947908459549
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProjectvToolsWindowHelpD AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph® ReportSort.php(e) Reporisonbirection.Kloskservice.php> M Mail• MeetingGeneratorO NotificationD OAuth2D RecallAl[ SecurityC StrategyStreamingD TeamTelephonyUserPilotM Webhook© AbstractService.php© ActivityProviderFactory.ph|© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php© IpapiClient.php© IpapiService.php© ParticipantShareService.ph© PlanhatService.php© PlaybackService.phpPlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorInterface.© ResolveTeamCrmConnecti© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php©TeamService.php© TranscodeParameterResol'© UserService.php© Uuid.php> C Traits› D UseCases> D User> D Utils• I validationv MVO~ D Repositoryv @ OnDemandActivitySears© Criteria.php© TranscriptionKeywordP:lests passed: (a minute ago© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© Criteria.phpAskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityServicenutdieeynocoutourere ainisenesonitActivityUpdatedDate::PARAM_UPDATED_FROM,ActivityUpdatedDate: :PARAM_UPDATED_TO,© TrackProviderInstalledEvent.phpClosingPeriodFilter::KEY_START_DATE,© CreateActivityLoggedEvent.php© UserPilotActivityListener.phpClosingPeriodFilter::KEY_END_DATE,(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.php11411511611711811912012111241 usagepublic function __constructCprivate readonly ActivitySearch SactivitySearch,privace readonly Elascicactivitykeposicory pelasclckeposicory.class Automacedкeрortskepo o:A15 X4 ^onwvare reaconly Loccerinuerace nLoddera) 6...3/**/*** Retrieve all standard (non-Ask Jiminny) m 38* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.39* Date filters stored on the saved search are excluded; if no other filters exist,* @param string $sortColumnThe column to40* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* dparam string ssortulrection ine sort dire41—42* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**= Criteria: :createFromRequest(* Retrieve all Ask Liminny reports createdAAccept meyeet$requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page: =* OodrdllusernusenThe user whos 51array_merge (SrequestParams,['Limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page']* @param string $sortColumnThe column t,52nuser-poernezone* Oparam string $sortDirection The sort dire53):* @return Collection<AutomatedReport>*/14 usages57public function getAskJiminnyReportsByUser(User $user,-59string $sortColumn = 'created_at',surno ssortutreccion = 'desc'): Collection {...J2 usagesprivate function buildSortedQuery(string $sor65/**-67* Get all active and enabled reports with ac—68* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>-7123 usagespublic function getActiveReportsByFrequency(s74* Oreturn string[] Activity IDs*/14 usagespublic function getActivitvIdsForSavedSearchdsearch ssavedsearch,user suser,): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyRepQrt] Fetched activity IDs for saved search', ['saved_search_id'→> $savedSearch->getId(),'user_id' => Suser-›getid(),'acuvity count'= count nacuvitviosi1):return SactivityIds:1 usageprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);toreacn Usaveosearch›getFilters() as $filter) €+key - эt-pcerngeuriuger Accept File &+X Reject File 0*€Support Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:17CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen Indlr tler var w nunwarusandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leams55:00uir-o( 4 spaces...
|
11054
|
|
11057
|
219
|
19
|
2026-04-14T09:10:20.910565+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157820910_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelpD AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph® ReportSort.php(e) Reporisonbirection.Kloskservice.php> M Mail• MeetingGeneratorNotificationDJ OAuth2D RecallAlD SecurityC StrategyStreamingD TeamTelephonyUserPilotM Webhook© AbstractService.php© ActivityProviderFactory.ph|© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php©IpapiClient.php©IpapiService.php© ParticipantShareService.ph© PlanhatService.php© PlaybackService.phpPlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorInterface.© ResolveTeamCrmConnecti© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php©TeamService.php© TranscodeParameterResol© UserService.php© Uuid.php› D Traits› D UseCases> D UserDUtils• I validationvIVO~ D Repositoryv @ OnDemandActivitySearc© Criteria.php© TranscriptionKeywordP:Tests passed: 1 (a minute ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php xAskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© Criteria.php<?phpdeclare(strict_types=1);(e TrackProvidernstallled-vent.ononamespace Jiminny\Component\ActivitySearch\Service;© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpuseclass ActivitySearchclass Automacedкeрortskepo o:815 X4 л83114115116117118119120121123/*** Retrieve all standard (non-Ask Jiminny) M107* @param string $sortColumnThe column tc* Cparam string ssortDirection The sort dir 109* @return Collection<AutomatedReport>11111212 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}113114115116 F1171/*** Retrieve all Ask Liminay reports created {119* Oodrdll usernusenIne user Ynos* @param string $sortColumnIne corumn cc* Oparam string $sortDirection The sort dire197* @return Collection<AutomatedReport>198*/—19914 usages200public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',surno ssortutreccion = 'desc'): Collection {...J2074254233234—2352 usages236private function buildSortedQuery(string $sor]237— 244/**245* Get all active and enabled reports with ac247* @param string $frequency148* dreturh coLcectzon<aucomaredкeport.L0723 usages260public function getActiveReportsByFrequency(s)7 usagesprivate Container $container;public function __construct(Container $container){.}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):/*** pretuea str ingt)9 usagespublic function getArrayFilterKeys(User $consumer): array{...;1 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollec1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}1 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:20CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filters•der aculvicvids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ctivitvourationRande → min duration = 1 Ttlters ouf o-second acrivitiesi• ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leamsTO/'2uir-o( 4 spaces...
|
NULL
|
-8044268755507340865
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelpD AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsSt© DealStagesService.p© RecipientsService.ph® ReportSort.php(e) Reporisonbirection.Kloskservice.php> M Mail• MeetingGeneratorNotificationDJ OAuth2D RecallAlD SecurityC StrategyStreamingD TeamTelephonyUserPilotM Webhook© AbstractService.php© ActivityProviderFactory.ph|© ActivityService.php© ApiResponseService.php© ConferenceService.php© InsightSeatService.php© InstantMeetingService.php© IntercomService.php©IpapiClient.php©IpapiService.php© ParticipantShareService.ph© PlanhatService.php© PlaybackService.phpPlaybackVideoOnlyService©PlaybookCategoryService./© PlaylistGeneratorInterface.© ResolveTeamCrmConnecti© SimpleThrottleService.php© SlackService.php© SocialAccountService.php© SoftPhoneService.phpC) TeamDeactivatedService.p© TeamOwnerService.php©TeamService.php© TranscodeParameterResol© UserService.php© Uuid.php› D Traits› D UseCases> D UserDUtils• I validationvIVO~ D Repositoryv @ OnDemandActivitySearc© Criteria.php© TranscriptionKeywordP:Tests passed: 1 (a minute ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php xAskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© Criteria.php<?phpdeclare(strict_types=1);(e TrackProvidernstallled-vent.ononamespace Jiminny\Component\ActivitySearch\Service;© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpuseclass ActivitySearchclass Automacedкeрortskepo o:815 X4 л83114115116117118119120121123/*** Retrieve all standard (non-Ask Jiminny) M107* @param string $sortColumnThe column tc* Cparam string ssortDirection The sort dir 109* @return Collection<AutomatedReport>11111212 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}113114115116 F1171/*** Retrieve all Ask Liminay reports created {119* Oodrdll usernusenIne user Ynos* @param string $sortColumnIne corumn cc* Oparam string $sortDirection The sort dire197* @return Collection<AutomatedReport>198*/—19914 usages200public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',surno ssortutreccion = 'desc'): Collection {...J2074254233234—2352 usages236private function buildSortedQuery(string $sor]237— 244/**245* Get all active and enabled reports with ac247* @param string $frequency148* dreturh coLcectzon<aucomaredкeport.L0723 usages260public function getActiveReportsByFrequency(s)7 usagesprivate Container $container;public function __construct(Container $container){.}public function getOnDemandPageFilters(): FilterDefinitionCollectionf...}public function get0nDemandPageFilterSet(Criteria $criteria, User $consumer): FilterDefinitreturn $this->getOnDemandPageFilters()-›withCriteria($criteria)-›withConsumer ($consumer)->withRestrictions($consumer->getTeam()):/*** pretuea str ingt)9 usagespublic function getArrayFilterKeys(User $consumer): array{...;1 usageprivate function getTeamInsightsPageFilters(bool $isExport = false): FilterDefinitionCollec1 usageprivate function getDealInsightsPageFilters(bool $useCreatedDate = false,booL pincLudebeallype = ralse.bool +inctuderipellhe - Talse): FilterDefinitionCollection {..}public function getTeamInsightsPageFilterSet(Criteria $criteria,User $consumer,bool $isExport = false): FilterDefinitionCollection i...rpublic function getDealInsightsPageFilterSet(Criteria $criteria,user consunen): FilterDefinitionCollectionf...}1 usagepublic function getTeamAiAutomationFilterSet(Criteria $criteria,User $consumerSupport Daily • in 2 h 50 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:10:20CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsE tatt tnt hperiod date filters•der aculvicvids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ctivitvourationRande → min duration = 1 Ttlters ouf o-second acrivitiesi• ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the serviceretumee uFix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Vew allliItlle win changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allAsk anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leamsTO/'2uir-o( 4 spaces...
|
NULL
|
|
11069
|
219
|
25
|
2026-04-14T09:11:12.113138+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157872113_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp, 0lablj Support Daily • in 2h 49 mA100% |45]Tue 14 Apr 12:11:11FV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vAskJiminnyReportActivityServiceT…DefaultsProject v© ReportController.phpyJiminnyDeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]Cascadev ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php xFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.phpAddLayoutEntities.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpNow let's run the test to verifv© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php XRequestGenerateAskJiminnyReportJobTest.php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrsronoCommand dockenwC DeallnsightsPeriodFilter(e TrackProvidernstallled-vent.onodeclare(strict_types=1);o desker nxe dovkcrs/ko3k Automwa/wprts/art1nan yReportActivityserviceTest-php --no-coverage0 DealinsidnisPeriodrilten© CreateActivityLoggedEvent.php© UserPilotActivityListener.phploul nor oen ndlr Tler var wi nunbarusang FilterDetinition.php(©) ActivityLogged.phpnamespace Jiminny\Component\ActivitySearch\Service;) Aulomaleakeporscallbackservice.onoc rterverntoncolectoCommand dockel© FilterDefinitionQuery.ph© RequestGenerateAskJiminnyReportJob.php› use ...© FilterDefinitionQueryColA Naalinn auna daalian lama 1 abaRequestGenerateReportJob.php© AutomatedReportResult.phpassesllesSymbolsActionsextProiect HllesvTiminnyReportActivityServiceTest.php --no-coverage• FilteredValueContainerliclass ActivitvSearch© IntMinMaxRange.php(C) AutomatedReport.phpQ- OnDemal[ AiActivityTypeclass Automacedкeрortskepo o:815 X4 л7 usages[ AiAutomationprivate Container $container;DOnDemandActivitySearch app/VO/Repository/OnDemandActivitySearchD AiCallScoring© OnDemandController.php•aoo nuo controlers Ariraee unvemanacontroler.ono&& php artisan testJiminnyReportActivityServiceTest.php --no-coverage 2>&1"D AskAnythingpublic function __construct(Container $container)f.© OnDemandActivitiesTransformer.php .../app/Http/Transformers/OnDemandActivitiesTransformer.phpD AskJiminnyAi* Retrieve all standard (non-Ask Jiminny) M• OnDemandLevel app/Component/AskJiminnyAi/OnDemandLevelDAWSpublic function get0nDemandPageFilters(): FilterDefir© OnDemandAskAnythingRequest.php .../app/Http/Requests/API/V2/OnDemandAskAnythingRequest.pM BillinaManagement59* @param string $sortColumnIne column tc-oe© OnDemandV2Controller.php.../app/Http/Controllers/API/V2/OnDemandV2Controller.phpM Cache* Oparam string $sortDirection The sort dire 107public function getOnDemandPageFilterSet(Criteria $crOnDemandActivitySearch build/coverage/VO/Repository/OnDemandActivitySearche artisan -maxdeoth 6 2>/dev/null | head -5"• CoachingFeedback_108OnDemandV2ControllerTest.php .../tests/Unit/Http/Controllers/Api/V2/OnDemandV2ControllerTest.p> D Country*orerurn coccecclonsauromceoreooro109return $this<> OnDemandController.php.html build/coverage/Http/Controllers/APl/PageD CustomerApi• Database->getOnDemandPageFilters()‹/ OnvemanoAcrvrescnstommerono.numi oullc/covercerruoanstommers12 usages111-›withCriteria($criteria)<> OndemandController.php.html build/coverage/Http/ControllersC Datadogpublic function getAllStandardReports(112->withConsumer($consumer)ninny && php artisan testJiminnyReportActivityServiceTest-php --no-coverage 2>&1"C DateTimestring $sortColumn = 'created_at',Deallnsights113->withRestrictions($consumer->getTeam()):string $sortDirection = 'desc'114_ DealRisksEasticsearch): Collection {...J115poy wen n resporatet ipamtereseempty when no results116 F>_tloquent> DEncoding/**1171 date filters* Retrieve all Ask Liminny reports created f118number to disable first r... 0.03s> D Encryption9 usagesDES* OodrdllusernusenThe user whos 119public function getArrayFilterKeys(User $consumer): aD Faker* @param string $sortColumnThe column tc 130• FeatureFlags* Oparam string $sortDirection The sort dire1 usageD FFMpeg1151private function getTeamInsightsPageFilters(bool $isEsence number in the request params, so criceria:: creater romkequest deraultea itlo 0• FileSystem- === 0, several implicit defaults were silently applied:* Oreturn Collection<AutomatedReport>1Y1D Geckoto-second acrivitiesD Gong14 usagesprivate function getDealInsightsPageFilters(corded activities only)GuzzleHttppublic function getAskJiminnyReportsByUser(199bool $useCreatedDate = false,KeyPointsUser $user,-200bool $includeDealType = false,• Kioskch disables these defaults - explaining why the frontend returned activities but the servicestring $sortColumn = 'created_at',bool $includePipeline = false,M LanquadeDetectionstring ssorcbirection = "desc"202): FilterDefinitionCollection {.+LiveFeed): Collection {...J232sequence_number' → 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequevukepositoryonbemaneAcuivilysearchOpen In Right SplitD Locks253public function getTeamInsightsPageFilterSet(lestadded: testoetAculvlcyLaspassesnonzerosequencenumberlob1sablerursckequestberau Lus asserts that the captured urlterla oblect nas 1shirs• MathZ usages1254cricerta pcracerta,tRequest() === false.• MediaPipelineprivate function buildSortedQuery(string $sor235user +consumer,Oul .• MeetingBot114250bool sisExport = false• MobileSettings115/**237): FilterDefinitionCollection {..| ModelNotitication116* Get all active and enabled reports with ac 244117Nudge245public function getDealInsightsPageFilterSet(118* @param string $frequency246Criteria $criteria,Vew allliParagraphBreakerItlle wiun changesv119247User $consumerapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1M ParticipantSpeech120* dreturn cocLectron<Aucomacedкeрort»248): Falterbefinitioncollection i...rReject allAccept allPartitionedCookie121D PlaybackPage258Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used ir23 usages1 usagePlaylist1124public function getActiveReportsByFrequency(:259pubLic tuncclon getleamA1AutomationFilterSet(123+ <> Code Claude Sonnet 4.6Tests passed: 1 (2 minutes ago)winasun leams118.duir-o( 4 spaces...
|
NULL
|
4475248259659255375
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelp, 0lablj Support Daily • in 2h 49 mA100% |45]Tue 14 Apr 12:11:11FV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vAskJiminnyReportActivityServiceT…DefaultsProject v© ReportController.phpyJiminnyDeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]Cascadev ServiceAulomaleakeporscommand.ono< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php xFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep© ActivityApiSearch.ph© ActivitySearch.php© AutomatedReportsSendCommand.phpAddLayoutEntities.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpNow let's run the test to verifv© UserOptionsByGrour© Team.php© AutomatedReportsRepository.php XRequestGenerateAskJiminnyReportJobTest.php© AbstractStageFilterDefil© AutomatedReportsService.phpC CreateHeldActivityEvent.phpActivitySearchServicePrsronoCommand dockenwC DeallnsightsPeriodFilter(e TrackProvidernstallled-vent.onodeclare(strict_types=1);o desker nxe dovkcrs/ko3k Automwa/wprts/art1nan yReportActivityserviceTest-php --no-coverage0 DealinsidnisPeriodrilten© CreateActivityLoggedEvent.php© UserPilotActivityListener.phploul nor oen ndlr Tler var wi nunbarusang FilterDetinition.php(©) ActivityLogged.phpnamespace Jiminny\Component\ActivitySearch\Service;) Aulomaleakeporscallbackservice.onoc rterverntoncolectoCommand dockel© FilterDefinitionQuery.ph© RequestGenerateAskJiminnyReportJob.php› use ...© FilterDefinitionQueryColA Naalinn auna daalian lama 1 abaRequestGenerateReportJob.php© AutomatedReportResult.phpassesllesSymbolsActionsextProiect HllesvTiminnyReportActivityServiceTest.php --no-coverage• FilteredValueContainerliclass ActivitvSearch© IntMinMaxRange.php(C) AutomatedReport.phpQ- OnDemal[ AiActivityTypeclass Automacedкeрortskepo o:815 X4 л7 usages[ AiAutomationprivate Container $container;DOnDemandActivitySearch app/VO/Repository/OnDemandActivitySearchD AiCallScoring© OnDemandController.php•aoo nuo controlers Ariraee unvemanacontroler.ono&& php artisan testJiminnyReportActivityServiceTest.php --no-coverage 2>&1"D AskAnythingpublic function __construct(Container $container)f.© OnDemandActivitiesTransformer.php .../app/Http/Transformers/OnDemandActivitiesTransformer.phpD AskJiminnyAi* Retrieve all standard (non-Ask Jiminny) M• OnDemandLevel app/Component/AskJiminnyAi/OnDemandLevelDAWSpublic function get0nDemandPageFilters(): FilterDefir© OnDemandAskAnythingRequest.php .../app/Http/Requests/API/V2/OnDemandAskAnythingRequest.pM BillinaManagement59* @param string $sortColumnIne column tc-oe© OnDemandV2Controller.php.../app/Http/Controllers/API/V2/OnDemandV2Controller.phpM Cache* Oparam string $sortDirection The sort dire 107public function getOnDemandPageFilterSet(Criteria $crOnDemandActivitySearch build/coverage/VO/Repository/OnDemandActivitySearche artisan -maxdeoth 6 2>/dev/null | head -5"• CoachingFeedback_108OnDemandV2ControllerTest.php .../tests/Unit/Http/Controllers/Api/V2/OnDemandV2ControllerTest.p> D Country*orerurn coccecclonsauromceoreooro109return $this<> OnDemandController.php.html build/coverage/Http/Controllers/APl/PageD CustomerApi• Database->getOnDemandPageFilters()‹/ OnvemanoAcrvrescnstommerono.numi oullc/covercerruoanstommers12 usages111-›withCriteria($criteria)<> OndemandController.php.html build/coverage/Http/ControllersC Datadogpublic function getAllStandardReports(112->withConsumer($consumer)ninny && php artisan testJiminnyReportActivityServiceTest-php --no-coverage 2>&1"C DateTimestring $sortColumn = 'created_at',Deallnsights113->withRestrictions($consumer->getTeam()):string $sortDirection = 'desc'114_ DealRisksEasticsearch): Collection {...J115poy wen n resporatet ipamtereseempty when no results116 F>_tloquent> DEncoding/**1171 date filters* Retrieve all Ask Liminny reports created f118number to disable first r... 0.03s> D Encryption9 usagesDES* OodrdllusernusenThe user whos 119public function getArrayFilterKeys(User $consumer): aD Faker* @param string $sortColumnThe column tc 130• FeatureFlags* Oparam string $sortDirection The sort dire1 usageD FFMpeg1151private function getTeamInsightsPageFilters(bool $isEsence number in the request params, so criceria:: creater romkequest deraultea itlo 0• FileSystem- === 0, several implicit defaults were silently applied:* Oreturn Collection<AutomatedReport>1Y1D Geckoto-second acrivitiesD Gong14 usagesprivate function getDealInsightsPageFilters(corded activities only)GuzzleHttppublic function getAskJiminnyReportsByUser(199bool $useCreatedDate = false,KeyPointsUser $user,-200bool $includeDealType = false,• Kioskch disables these defaults - explaining why the frontend returned activities but the servicestring $sortColumn = 'created_at',bool $includePipeline = false,M LanquadeDetectionstring ssorcbirection = "desc"202): FilterDefinitionCollection {.+LiveFeed): Collection {...J232sequence_number' → 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequevukepositoryonbemaneAcuivilysearchOpen In Right SplitD Locks253public function getTeamInsightsPageFilterSet(lestadded: testoetAculvlcyLaspassesnonzerosequencenumberlob1sablerursckequestberau Lus asserts that the captured urlterla oblect nas 1shirs• MathZ usages1254cricerta pcracerta,tRequest() === false.• MediaPipelineprivate function buildSortedQuery(string $sor235user +consumer,Oul .• MeetingBot114250bool sisExport = false• MobileSettings115/**237): FilterDefinitionCollection {..| ModelNotitication116* Get all active and enabled reports with ac 244117Nudge245public function getDealInsightsPageFilterSet(118* @param string $frequency246Criteria $criteria,Vew allliParagraphBreakerItlle wiun changesv119247User $consumerapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1M ParticipantSpeech120* dreturn cocLectron<Aucomacedкeрort»248): Falterbefinitioncollection i...rReject allAccept allPartitionedCookie121D PlaybackPage258Explain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used ir23 usages1 usagePlaylist1124public function getActiveReportsByFrequency(:259pubLic tuncclon getleamA1AutomationFilterSet(123+ <> Code Claude Sonnet 4.6Tests passed: 1 (2 minutes ago)winasun leams118.duir-o( 4 spaces...
|
NULL
|
|
11070
|
219
|
26
|
2026-04-14T09:11:18.145849+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157878145_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl, folder
ActionItems, folder
Activity, folder
ActivityAnalytics, folder
ActivitySearch, folder
EventSubscriber, folder
FilterDefinition, folder
Service
ActivityApiSearch.php, class
ActivitySearch.php, class
UserOptionsByGroup.php, class
AbstractStageFilterDefinition.php, abstract class
ActivitySearchServiceProvider.php, final class
DealInsightsPeriodFilterFactory.php
DealInsightsPeriodFilterFactoryInterface.php, interface
FilterDefinition.php, abstract class
FilterDefinitionCollection.php, class
FilterDefinitionQuery.php, class
FilterDefinitionQueryCollection.php, class
FilteredValueContainerInterface.php, interface
IntMinMaxRange.php, class
AiActivityType
AiAutomation
AiCallScoring
AskAnything
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model
Notification
Nudge
ParagraphBreaker
ParticipantSpeech
PartitionedCookie
PlaybackPage
Playlist
Prophet
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.57539064,"top":0.13055556,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.58632815,"top":0.13055556,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.59765625,"top":0.12916666,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.60625,"top":0.12916666,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"EventSubscriber, folder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinition, folder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Service","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityApiSearch.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UserOptionsByGroup.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AbstractStageFilterDefinition.php, abstract class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearchServiceProvider.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsPeriodFilterFactory.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsPeriodFilterFactoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinition.php, abstract class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionCollection.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionQuery.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilterDefinitionQueryCollection.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"FilteredValueContainerInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"IntMinMaxRange.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playlists","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Postmark","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Reports","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"role_description":"text"}]...
|
-1792450594297658947
|
-5824280404149933980
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl, folder
ActionItems, folder
Activity, folder
ActivityAnalytics, folder
ActivitySearch, folder
EventSubscriber, folder
FilterDefinition, folder
Service
ActivityApiSearch.php, class
ActivitySearch.php, class
UserOptionsByGroup.php, class
AbstractStageFilterDefinition.php, abstract class
ActivitySearchServiceProvider.php, final class
DealInsightsPeriodFilterFactory.php
DealInsightsPeriodFilterFactoryInterface.php, interface
FilterDefinition.php, abstract class
FilterDefinitionCollection.php, class
FilterDefinitionQuery.php, class
FilterDefinitionQueryCollection.php, class
FilteredValueContainerInterface.php, interface
IntMinMaxRange.php, class
AiActivityType
AiAutomation
AiCallScoring
AskAnything
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model
Notification
Nudge
ParagraphBreaker
ParticipantSpeech
PartitionedCookie
PlaybackPage
Playlist
Prophet
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class...
|
11069
|
|
11094
|
219
|
37
|
2026-04-14T09:12:32.359820+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157952359_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:C ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D ControllersV MAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (3 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGAskJIminnykepor Acuivilyservice.ongACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller41 M2 ^(e TrackProvidernstallled-vent.ono241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp→ ounouLbala lllessauer© CreateActivityLoggedEvent.php© UserPilotActivityListener.php262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic263'history' => $this->historyService->getHistory($user,identifier: HistoryService::• ActivityLogged.phpAutomatedReportsCallbackService.php264C RequestGenerateAskJiminnyReportJob.php265266$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId()):RequestGenerateReportJob.php© AutomatedReportResult.phpif ($teamAiContext?->getPrompt() !== null) {(C) AutomatedReport.php268"reouescvaral'teanaucontext' = "reanazcontext->deurronotoclass Automacedкeрortskepo o:A15 X4 Av20961627593114115116117118119121123LI4/**273* Retrieve all standard (non-Ask Jiminny) M274* @param string $sortColumnThe column to276*dparam string ssortulrection ine sort dire277* @return Collection<AutomatedReport>.278279*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]84285/**286287* Retrieve all Ask Liminny reports created A288* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column te290* Oparam string $sortDirection The sort dire2911475* @return Collection<AutomatedReport>294*/-29514 usages296public function getAskJiminnyReportsByUser(User $user,298string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}300301—302Z usagesprivate function buildSortedQuery(string $sor]305504/**—305306* Get all active and enabled reports with ac—307308* @param string $frequency309— 310* dreturh coLcectzon<aucomacedкeрort>31131223 usagespublic function getActiveReportsByFrequency(s)314$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeot):rerur uns-porooneroeru ce-poerotreanecuraoorteoresconsestreankeovest, "strealikecuest.onCompleted: function (string $assistantResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {// Remove in-progress eventSthis->historyService->removeLastEventMessageByType($user,identifier: HistoryService: : ON_DEMAND_SERVICE,type: HistorvService::EVENT IN PROGRESS TYPE// Save to history if backend completed successfully (even if client discor// Only skip saving if there was an actual error during streamingif (! $hadError && ! empty(trim($assistantResponse))) {$this->historyService->appendToSystemHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$assistantResponse,, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:32CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land ioash —eSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisaniminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest-php --no-coverage 2>61"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturnsfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51 - added 'sequence_number' = 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.sequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirsO filesystems.phprlleutiiong• FilterNormalizer.php app/UtilsrleutllestonoFlesvstem-xcention.ohvFileNotFoundException.php app/Exceptions/Fltervormalizerlect.ohnO Filter.phpO FileService.phpReportActivityService.php +1 -1O FilterDefinition.phpExplain it to me again. Why is there issue with that? Where is it expected and wy do I need to fork with that. How is it used in efi y+ <> CodeClaude Sonnet 4.6Öul ..Vew allliReject allAccept allWinasun leams298:48uir-o( 4 spaces...
|
NULL
|
6021502683580180874
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js v#11894 on JY-18909-automated-reports-ask-liminny k vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:C ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D ControllersV MAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (3 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGAskJIminnykepor Acuivilyservice.ongACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller41 M2 ^(e TrackProvidernstallled-vent.ono241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp→ ounouLbala lllessauer© CreateActivityLoggedEvent.php© UserPilotActivityListener.php262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic263'history' => $this->historyService->getHistory($user,identifier: HistoryService::• ActivityLogged.phpAutomatedReportsCallbackService.php264C RequestGenerateAskJiminnyReportJob.php265266$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId()):RequestGenerateReportJob.php© AutomatedReportResult.phpif ($teamAiContext?->getPrompt() !== null) {(C) AutomatedReport.php268"reouescvaral'teanaucontext' = "reanazcontext->deurronotoclass Automacedкeрortskepo o:A15 X4 Av20961627593114115116117118119121123LI4/**273* Retrieve all standard (non-Ask Jiminny) M274* @param string $sortColumnThe column to276*dparam string ssortulrection ine sort dire277* @return Collection<AutomatedReport>.278279*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]84285/**286287* Retrieve all Ask Liminny reports created A288* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column te290* Oparam string $sortDirection The sort dire2911475* @return Collection<AutomatedReport>294*/-29514 usages296public function getAskJiminnyReportsByUser(User $user,298string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}300301—302Z usagesprivate function buildSortedQuery(string $sor]305504/**—305306* Get all active and enabled reports with ac—307308* @param string $frequency309— 310* dreturh coLcectzon<aucomacedкeрort>31131223 usagespublic function getActiveReportsByFrequency(s)314$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeot):rerur uns-porooneroeru ce-poerotreanecuraoorteoresconsestreankeovest, "strealikecuest.onCompleted: function (string $assistantResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {// Remove in-progress eventSthis->historyService->removeLastEventMessageByType($user,identifier: HistoryService: : ON_DEMAND_SERVICE,type: HistorvService::EVENT IN PROGRESS TYPE// Save to history if backend completed successfully (even if client discor// Only skip saving if there was an actual error during streamingif (! $hadError && ! empty(trim($assistantResponse))) {$this->historyService->appendToSystemHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$assistantResponse,, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:32CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land ioash —eSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisaniminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest-php --no-coverage 2>61"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturnsfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51 - added 'sequence_number' = 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.sequencenumberloD1sablerirsckequestberauuus asserts that the captured uriteria ob ect nas 1srirsO filesystems.phprlleutiiong• FilterNormalizer.php app/UtilsrleutllestonoFlesvstem-xcention.ohvFileNotFoundException.php app/Exceptions/Fltervormalizerlect.ohnO Filter.phpO FileService.phpReportActivityService.php +1 -1O FilterDefinition.phpExplain it to me again. Why is there issue with that? Where is it expected and wy do I need to fork with that. How is it used in efi y+ <> CodeClaude Sonnet 4.6Öul ..Vew allliReject allAccept allWinasun leams298:48uir-o( 4 spaces...
|
NULL
|
|
11095
|
219
|
38
|
2026-04-14T09:12:35.407620+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776157955407_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:C ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D Controllersv MAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (3 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykepor Acuivilyservice.ongACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller41 M2 ^(e TrackProvidernstallled-vent.ono241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp→ ounouLbala lllessauer© CreateActivityLoggedEvent.php© UserPilotActivityListener.php262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic263'history' => $this->historyService->getHistory($user,identifier: HistoryService::• ActivityLogged.phpAutomatedReportsCallbackService.php264C RequestGenerateAskJiminnyReportJob.php265266$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());RequestGenerateReportJob.php© AutomatedReportResult.phpif ($teamAiContext?->getPrompt() !== null) {(C) AutomatedReport.php268"reouescvaral'teanaucontext' = "reanazcontext->deurronotoclass Automacedкeрortskepo o:A15 X4 Av20%61627593114115116117118119121123LI4/**273* Retrieve all standard (non-Ask Jiminny) M274* @param string $sortColumnThe column to276*dparam string ssortulrection ine sort dire277* @return Collection<AutomatedReport>.278279*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]84285/**286287* Retrieve all Ask Liminny reports created A288* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column te290* Oparam string $sortDirection The sort dire2911475* @return Collection<AutomatedReport>294*/-29514 usages296public function getAskJiminnyReportsByUser(User $user,298string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J300301—302Z usagesprivate function buildSortedQuery(string $sor]305504/**—305306* Get all active and enabled reports with ac—307308* @param string $frequency309— 310* dreturn cocLectron<Aucomacedкeрort»31131223 usagespublic function getActiveReportsByFrequency(s)314$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeou):rerur uns-porooneroeru ce-poerotreanecuraoorteoresconsestreankeovest, "strealikecuest.onCompleted: function (string $assistantResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {// Remove in-progress eventSthis->historyService->removeLastEventMessageByType($user,identifier: HistoryService: : ON_DEMAND_SERVICE,type: HistorvService::EVENT IN PROGRESS TYPE// Save to history if backend completed successfully (even if client discor// Only skip saving if there was an actual error during streamingif (! $hadError && ! empty(trim($assistantResponse))) {$this->historyService->appendToSystemHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$assistantResponse,, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:35CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ..Now let's run the test to verifvdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsperiod date filters1de handtes scalyr flttersget activity ids hassees sn zero sequence number to disable first r._ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]<>CodeClaude Sonnet 4.6W Windsurf Teams298:48uir-o( 4 spaces...
|
NULL
|
-4836243511905384773
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLivecoaching© Managescim-orleam.p(c Malkoanchrocnvronnl© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:C ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› C Helpersv UHttp> MAccessTokenProviderv D Controllersv MAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (3 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykepor Acuivilyservice.ongACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpCrealenelaAcuviyevent.onoOnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpC) RequestGenerateAskJiminnyReportJobTest.phpclass OnDemandV2Controller extends Controller41 M2 ^(e TrackProvidernstallled-vent.ono241public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse |JsonResp→ ounouLbala lllessauer© CreateActivityLoggedEvent.php© UserPilotActivityListener.php262'callIds' => $this->historyService->getContextIds($user,identifier: HistoryServic263'history' => $this->historyService->getHistory($user,identifier: HistoryService::• ActivityLogged.phpAutomatedReportsCallbackService.php264C RequestGenerateAskJiminnyReportJob.php265266$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());RequestGenerateReportJob.php© AutomatedReportResult.phpif ($teamAiContext?->getPrompt() !== null) {(C) AutomatedReport.php268"reouescvaral'teanaucontext' = "reanazcontext->deurronotoclass Automacedкeрortskepo o:A15 X4 Av20%61627593114115116117118119121123LI4/**273* Retrieve all standard (non-Ask Jiminny) M274* @param string $sortColumnThe column to276*dparam string ssortulrection ine sort dire277* @return Collection<AutomatedReport>.278279*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {..[PHONE]84285/**286287* Retrieve all Ask Liminny reports created A288* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column te290* Oparam string $sortDirection The sort dire2911475* @return Collection<AutomatedReport>294*/-29514 usages296public function getAskJiminnyReportsByUser(User $user,298string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J300301—302Z usagesprivate function buildSortedQuery(string $sor]305504/**—305306* Get all active and enabled reports with ac—307308* @param string $frequency309— 310* dreturn cocLectron<Aucomacedкeрort»31131223 usagespublic function getActiveReportsByFrequency(s)314$this->historyService->appendToUserHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$inputData[ 'message']):$this->historyService->appendToEventHistory(user: $user,identifier: HistoryService::0N_DEMAND_SERVICE,type: HistoryService::EVENT_IN_PROGRESS_TYPE):$streamRequest = StreamRequest: :onDemandLevel($requestData);// Track active stream in Redis$this->activeStreamsRepository->start($user->getId(),$streamRequest->getId(),ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeou):rerur uns-porooneroeru ce-poerotreanecuraoorteoresconsestreankeovest, "strealikecuest.onCompleted: function (string $assistantResponse,bool $clientAborted,bool $hadError,) use ($user, $streamRequest) {// Remove in-progress eventSthis->historyService->removeLastEventMessageByType($user,identifier: HistoryService: : ON_DEMAND_SERVICE,type: HistorvService::EVENT IN PROGRESS TYPE// Save to history if backend completed successfully (even if client discor// Only skip saving if there was an actual error during streamingif (! $hadError && ! empty(trim($assistantResponse))) {$this->historyService->appendToSystemHistory($user,identifier: HistoryService::0N_DEMAND_SERVICE,$assistantResponse,, 0lablf Support Daily • in 2h 48 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:12:35CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ..Now let's run the test to verifvdesker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coverageloul nor oen Indlr tler var w nunwarusandoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockerocker exec oocker land 1oash -dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker lamp 1 bash -c "find / -name artisan -maxdeoth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTesta fittersemoty when no resultsperiod date filters1de handtes scalyr flttersget activity ids hassees sn zero sequence number to disable first r._ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 ilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and wy do l need to fork with that. How is it used [EMAIL]<>CodeClaude Sonnet 4.6W Windsurf Teams298:48uir-o( 4 spaces...
|
11094
|
|
11115
|
219
|
47
|
2026-04-14T09:13:23.583515+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158003583_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProvider~ D ControllersV DAPI> DAiCallScoringD AReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (4 minutes ago)© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc 106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac 223.* @param string $frequency140121124125—126* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s15activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user():itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezone)terSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $uselidationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,$onDemandActivitySearchCriteria,$filterS.s->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAL1as::HTTP_0K)*(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error'=ne->oerressade'user_id'=> $user->getId(),irn new JsonResponse(['ids' => [],'error"'Failed to fetch activity IDs',status: ResponseAL1as::HTTP_INTERNAL_SERVER_ERROR)NloalSupport Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:23CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sandecke nte/sdocxes /kLosk/Ruonape/arports/ASkJ1ninyReportActivityservicetest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest- php --no-coverage 2>&1"PASSNAucomaLeanepores Askstminnyneportactevilyserviceresemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (fiiters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirs-Requesto zzz tallse.Öul ..1 file with changesapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Vew allliReject allAccept allExplain it to me aaain. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used inPSW Windsurf Teams9567uir-o( 4 spaces...
|
NULL
|
-3642487540369125113
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComi© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProvider~ D ControllersV DAPI> DAiCallScoringD AReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACONTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareContTests passed: 1 (4 minutes ago)© ReportController.phpC AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc 106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac 223.* @param string $frequency140121124125—126* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s15activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user():itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezone)terSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $uselidationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,$onDemandActivitySearchCriteria,$filterS.s->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAL1as::HTTP_0K)*(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error'=ne->oerressade'user_id'=> $user->getId(),irn new JsonResponse(['ids' => [],'error"'Failed to fetch activity IDs',status: ResponseAL1as::HTTP_INTERNAL_SERVER_ERROR)NloalSupport Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:23CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Now let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sandecke nte/sdocxes /kLosk/Ruonape/arports/ASkJ1ninyReportActivityservicetest. php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker vand ioash —dSid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan testdests/unxe/servaces/K1osk/AusomatedReports/AskJ1maynyReportActivaty5erviceTest- php --no-coverage 2>&1"PASSNAucomaLeanepores Askstminnyneportactevilyserviceresemoty when no resultsperiod date filters1ds handles scrayr tittersids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (fiiters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirs-Requesto zzz tallse.Öul ..1 file with changesapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Vew allliReject allAccept allExplain it to me aaain. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used inPSW Windsurf Teams9567uir-o( 4 spaces...
|
NULL
|
|
11116
|
219
|
48
|
2026-04-14T09:13:26.564212+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158006564_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© AskJiminnyReportActivityServiceTest.php© HistoryService.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc 106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac222* @param string $frequency140121124125—126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(s157activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user(0):itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', (default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezoneterSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $useridationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,1)->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,monvelanorcoutyoearchuteria, onureros->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAlias::HTTP_0K);(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error' => $e-›getMessage(),'user_id'→ ser-roerloirn new JsonResponse(['ids' »> [].'error"'Failed to fetch activity IDs',status: ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);Pulon nasunanceocontex:Filter(Request $request, User $user): boolf...}Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:26+D ..Tests passed: 1 (4 minutes ago)CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepNow let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioasn —Sid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivitvourationRande → min duration = 1 Ttlters ouf o-second activifiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Itlle wiun changesv1l/Sethicha/kios /AutomatedReports/D AskJiminyReportActivityService.,php +1 - 1Vew allliReject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Winasun leams95:67uir-o( 4 spaces...
|
NULL
|
7239342745067674649
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProject vViewNavigateC PhpStormFileEditFV faVsco.jsProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrocnvronnlc Mureu canzercnanner© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards› Helpersv DHttp> MAccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • ScorecardsSettingsTeamInsightsThemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log< console EUi= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phpA console [PROD]© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© AskJiminnyReportActivityServiceTest.php© HistoryService.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:© Criteria.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass Automacedкeрortskepo o:A15 X4 л611141151161171181191211124123/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column to* dodron scrino osorcuurection ine sort oulre* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J100101/**102* Retrieve all Ask Jiminny reports created 2103.104* Oodrdll usernusenThe user whos 10s* @param string $sortColumnThe column tc 106* Oparam string $sortDirection The sort dire107* @return Collection<AutomatedReport>109*/11014 usages-111public function getAskJiminnyReportsByUser(112-113User $user,string $sortColumn = 'created_at',114115string ssorcbirection = "desc"): Collection {...J1162 usagesprivate function buildSortedQuery(string $sor 119/*** Get all active and enabled reports with ac222* @param string $frequency140121124125—126* dreturh coLcectzon<aucomacedкeрort>23 usages12271public function getActiveReportsByFrequency(s157activitySearchCc W .*class OnDemandV2Controller extends ControllerA1X2 A Vpublic function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepositor: User $user */$request->user(0):itureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {lrnsreatureuneckIit = Srequest->input( key: 'top_count', (default: self::DEFAULT_TOP_ACTIVITIES_COUNT);lways fetch first N (top count) IDslemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequestiarray_merge($request->all(), ['limit' => $topCount,'page' = 1l),$user->getTimezoneterSet = $this->activitySearch->get0nDemandPageFilterSet($onDemandActivitySearchCriteria, $useridationRules = $filterSet->getValidationRules()->merge (['exclude' => 'array'.'Limit' => 'integer|min:1|max:'• $topCount,1)->alL():vest->validate($validationRules);:ChangedFilters = $this->hasChangedContextFilter($request, $user);ivityIds = $repository->onDemandSearchIds0nly($user,monvelanorcoutyoearchuteria, onureros->historyService->storeContextIds($user,identifier: HistoryService::CONTEXT_IDS, $activityIds);irn new JsonResponse(['count'=> count($activityIds),'changed_context_filters' => $hasChangedFilters,status: ResponseAlias::HTTP_0K);(Exception $e) {s->logger-›error('Failed to fetch activity IDs for Ask Liminnx', ['error' => $e-›getMessage(),'user_id'→ ser-roerloirn new JsonResponse(['ids' »> [].'error"'Failed to fetch activity IDs',status: ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);Pulon nasunanceocontex:Filter(Request $request, User $user): boolf...}Support Daily • in 2h 47 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:13:26+D ..Tests passed: 1 (4 minutes ago)CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepNow let's run the test to verifvtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coverageloul nor oen nolt tler var w nunwaru sandecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand docker•cocker exec oocker land ioasn —Sid php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestemoty when no resultsE tatt tnt hperiod date filtershand lesids bassess snazer fsequence number to disable first _ 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivitvourationRande → min duration = 1 Ttlters ouf o-second activifiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned 0.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetActi1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest () === false.Öul ..Itlle wiun changesv1l/Sethicha/kios /AutomatedReports/D AskJiminyReportActivityService.,php +1 - 1Vew allliReject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL]‹> CodeClaude Sonnet 4.6Winasun leams95:67uir-o( 4 spaces...
|
11115
|
|
11117
|
219
|
49
|
2026-04-14T09:13:44.926791+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158024926_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorTools#1894 on.lY-18909-automated-renorts-ask-liminnvWindowHelpProject v© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg› D Formats› D Guards> D Helpersv UHttp> DJ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D Settings> D Teaminsights•nemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybebuecommana.ongAutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 ^6162/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcuurection ine sor a* @return Collection<AutomatedReport>*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/*** Retrieve all Ask Liminny reports create* Oodrdll usernusenIne user* @param string $sortColumnThe column* Oparam string $sortDirection The sort a* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUserUser $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© OnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.phpA console [PROD]© ActivitySearch.pnp© Criteria.phpFind in Flles100+ matches in 26+ fllesFile mask*.phpsequenceIn ProjectModuleDirectoryScopeI/ Expand the chunk to a valid UTF-8 sequenceProphetClient.php 162private ?int Ssequence Number = null;ActivityLog.php 16public function geiSequenceNumber(): ?intActivityLog.php 43return Sthis-> sequenceNumber;ActivityLog.php 45public function hasSequenceNumber(): boolActivityLog.php 48etum onis-›secuencerumoer == nuirActivityLog.php 50public function sefSequenceNumber(?int #sequenceNumber): ActivityLogActivityLog.php 53Sthis->sequenceNumber = $sequence Number;ActivityLog.php 55protected $sequenceNumber;Conferences/ConferenceEvent.php 36* @param nulllint #sequenceNumberConferences/ConferenceEvent.php 48public function _construct(Activity $activity, ?string $context = null, ?int $sequence Nui Conferences/ConferenceEvent.php 50Sthis->sequenceNumber = Ssequence Vumber;Conferences/ConferenceEvent.php 54public function geiSequence Number(): ?intConferences/ConferenceEvent.php 72return Sthis->seqnceNumber;Conferences/ConferenceEvent.php 74protected Ssequence Number;ConnectionEvent.php 30* @param int|null $sequenceNumberConnectionEvent.php 41->orderBy(sequence', 'asc');API/ActivityController.php 1833ActivityDurationRange.php app/Component/ActivitySearch/FilterDefinitionprivate function getLowerBoundary(): ?intif ($this->criteria->hasMinDurationO)) {retur uns-ocrrera-oetranuuraron.oreturn $this->criteria->isFirstRequest()? static::INITIAL_MIN: nult;private function getUpperBoundary(): ?intif ($this->criteria->hasMaxDurationO)) {return punis->eriterla->gechaxburactono.2 usages110093114115116117118119121private function buildSortedQuery(string $101recurn nuee./*** Get all active and enabled reports with104* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»103105106107110811A9 Atprivate function getValue(): arrayreturn [$this->getLowerBoundary(), $this->getUpperBoundaryO];23 usages• Open results in new tabOpen in Find Window1124123public function getActiveReportsByFrequency(sSupport Daily • in 2h 47 mAAsk.liminnvRenortActivitvServicel.. De aults100% C•Tue 14 Apr 12:13:44CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Nowersrunthe esto vertvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockerdecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6W Windsurf Teams95:67uir-oia 4 space...
|
NULL
|
-6248265976633033538
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorTools#1894 on.lY-18909-automated-renorts-ask-liminnvWindowHelpProject v© JiminnyDebugCommanc©JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg› D Formats› D Guards> D Helpersv UHttp> DJ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D Settings> D Teaminsights•nemes> MUserAutomatedRepov DV2© ActivityV2ControlAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpJiminnybebuecommana.ongAutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 X4 ^6162/*** Retrieve all standard (non-Ask Jiminny)* @param string $sortColumnThe column* dodron scrino osorcuurection ine sor a* @return Collection<AutomatedReport>*/12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J/*** Retrieve all Ask Liminny reports create* Oodrdll usernusenIne user* @param string $sortColumnThe column* Oparam string $sortDirection The sort a* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUserUser $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...}= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© OnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.phpA console [PROD]© ActivitySearch.pnp© Criteria.phpFind in Flles100+ matches in 26+ fllesFile mask*.phpsequenceIn ProjectModuleDirectoryScopeI/ Expand the chunk to a valid UTF-8 sequenceProphetClient.php 162private ?int Ssequence Number = null;ActivityLog.php 16public function geiSequenceNumber(): ?intActivityLog.php 43return Sthis-> sequenceNumber;ActivityLog.php 45public function hasSequenceNumber(): boolActivityLog.php 48etum onis-›secuencerumoer == nuirActivityLog.php 50public function sefSequenceNumber(?int #sequenceNumber): ActivityLogActivityLog.php 53Sthis->sequenceNumber = $sequence Number;ActivityLog.php 55protected $sequenceNumber;Conferences/ConferenceEvent.php 36* @param nulllint #sequenceNumberConferences/ConferenceEvent.php 48public function _construct(Activity $activity, ?string $context = null, ?int $sequence Nui Conferences/ConferenceEvent.php 50Sthis->sequenceNumber = Ssequence Vumber;Conferences/ConferenceEvent.php 54public function geiSequence Number(): ?intConferences/ConferenceEvent.php 72return Sthis->seqnceNumber;Conferences/ConferenceEvent.php 74protected Ssequence Number;ConnectionEvent.php 30* @param int|null $sequenceNumberConnectionEvent.php 41->orderBy(sequence', 'asc');API/ActivityController.php 1833ActivityDurationRange.php app/Component/ActivitySearch/FilterDefinitionprivate function getLowerBoundary(): ?intif ($this->criteria->hasMinDurationO)) {retur uns-ocrrera-oetranuuraron.oreturn $this->criteria->isFirstRequest()? static::INITIAL_MIN: nult;private function getUpperBoundary(): ?intif ($this->criteria->hasMaxDurationO)) {return punis->eriterla->gechaxburactono.2 usages110093114115116117118119121private function buildSortedQuery(string $101recurn nuee./*** Get all active and enabled reports with104* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»103105106107110811A9 Atprivate function getValue(): arrayreturn [$this->getLowerBoundary(), $this->getUpperBoundaryO];23 usages• Open results in new tabOpen in Find Window1124123public function getActiveReportsByFrequency(sSupport Daily • in 2h 47 mAAsk.liminnvRenortActivitvServicel.. De aults100% C•Tue 14 Apr 12:13:44CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Nowersrunthe esto vertvwtests/Unxt/Servsces/Kiosk/Automate/meports/AskJ1minnyreportActivätyserviceTest-php --no-coveragecould not open input Tile: /var/www/ncml/artisanCommand dockerdecke nte/sdocxes /Losk/RuPonape/arports/ASkJ1ninyReportActivityservicetest, php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -c&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homeiminny && php artisan test•dests/unxe/servkces/K1osk/AusomatedReports/AskJ1maynyReportActiVatyServiceTest.php --no-coverage 2>&1"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixKoOL cause: bu1 Ldkequestraramst romsearch never set sequence number In the request params, so criterla::creater romkequest delaulted lt to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' → 1 to the Criteria: : createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.lest added: testbetacc1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Oul .Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6W Windsurf Teams95:67uir-oia 4 space...
|
NULL
|
|
11123
|
219
|
52
|
2026-04-14T09:13:57.880913+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158037880_m2.jpg...
|
PhpStorm
|
faVsco.js – OnDemandV2Controller.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
activitySearch
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
1/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.30546874,"top":0.13472222,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.3203125,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"activitySearch","depth":4,"bounds":{"left":0.33320314,"top":0.13402778,"width":0.0515625,"height":0.013888889},"value":"activitySearch","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.3953125,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.40703124,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4171875,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.42734376,"top":0.13402778,"width":0.00859375,"height":0.015277778},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1/2","depth":4,"bounds":{"left":0.44335938,"top":0.13333334,"width":0.030078124,"height":0.015277778},"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.4734375,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.48359376,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.49375,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.50390625,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.5992187,"top":0.13263889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.57539064,"top":0.15972222,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.58632815,"top":0.15972222,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.59765625,"top":0.15833333,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.60625,"top":0.15833333,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","depth":4,"bounds":{"left":0.30820313,"top":0.15694444,"width":0.38359374,"height":0.84305555},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Exception;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Validation\\ValidationException;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Component\\AskAnything\\HistoryService;\nuse Jiminny\\Component\\AskJiminnyAi\\Exceptions\\AskJiminnyException;\nuse Jiminny\\Component\\AskJiminnyAi\\OnDemandLevel\\Events\\AskAnythingAbortedChatCompleted;\nuse Jiminny\\Component\\Prophet\\ProphetService;\nuse Jiminny\\Component\\ProphetAi\\StreamRequest;\nuse Jiminny\\Events\\EventDispatcher;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Requests\\API\\V2\\OnDemandAskAnythingRequest;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActiveStreamsRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamAiContextRepository;\nuse Jiminny\\Utils\\FilterNormalizer;\nuse Jiminny\\VO;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response as ResponseAlias;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass OnDemandV2Controller extends Controller\n{\n use AuthorizesRequests;\n\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array FILTER_KEY_EXCLUDED_PARAMS = [\n 'sequence_number',\n 'page',\n 'per_page',\n 'limit',\n 'offset',\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly HistoryService $historyService,\n private readonly ProphetService $prophetService,\n private readonly TeamAiContextRepository $teamAiContextRepository,\n private readonly ActiveStreamsRepository $activeStreamsRepository,\n private readonly EventDispatcher $eventDispatcher,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled\n */\n private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse\n {\n if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {\n return new JsonResponse([\n 'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',\n ], ResponseAlias::HTTP_FORBIDDEN);\n }\n\n return null;\n }\n\n /**\n * Get top N activity IDs for Ask Jiminny feature based on filters\n *\n * @throws ValidationException\n * @throws ActivityProviderException\n */\n public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n $topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);\n\n try {\n // Always fetch first N (top count) IDs\n $onDemandActivitySearchCriteria = VO\\Repository\\OnDemandActivitySearch\\Criteria::createFromRequest(\n array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);\n\n $validationRules = $filterSet->getValidationRules()\n ->merge([\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:' . $topCount,\n ])\n ->all();\n\n $request->validate($validationRules);\n\n $hasChangedFilters = $this->hasChangedContextFilter($request, $user);\n $activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);\n $this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);\n\n return new JsonResponse([\n 'count' => count($activityIds),\n 'changed_context_filters' => $hasChangedFilters,\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'ids' => [],\n 'error' => 'Failed to fetch activity IDs',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n private function hasChangedContextFilter(Request $request, User $user): bool\n {\n $filterKey = $this->makeFilterKey($request);\n\n $result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);\n\n if (! $result['changed']) {\n return false;\n }\n\n if ($result['matches_previous']) {\n return false;\n }\n\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n // If no history or last event already matches, return false\n if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {\n return false;\n }\n\n // Append event and notify\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_FILTERS_CHANGED_TYPE\n );\n\n return true;\n }\n\n private function makeFilterKey(Request $request): string\n {\n $filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);\n\n try {\n $normalizedFilters = FilterNormalizer::normalizeFilters($filters);\n $json = json_encode(\n $normalizedFilters,\n JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR\n );\n\n return hash('xxh3', $json);\n } catch (\\JsonException $e) {\n $this->logger->error('Failed to encode filters', [\n 'error' => $e->getMessage(),\n 'filters_keys' => array_keys($filters),\n ]);\n\n throw new AskJiminnyException('Failed to create filter key', 0, $e);\n }\n }\n\n\n /**\n * Get Ask Anything conversation history\n */\n public function getAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse($history, ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to fetch Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'history' => [],\n 'error' => 'Failed to fetch history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Delete Ask Anything conversation history\n */\n public function deleteAskAnythingHistory(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);\n\n return new JsonResponse([\n 'message' => 'History deleted successfully',\n ], ResponseAlias::HTTP_OK);\n } catch (Exception $e) {\n $this->logger->error('Failed to delete Ask Anything history', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to delete history',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n /**\n * Ask Anything - submit question and get AI response\n */\n public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->logger->info('AskAnything request received', [\n 'user_id' => $user->getId(),\n 'team_id' => $user->getTeamId(),\n 'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),\n 'message_preview' => mb_substr($request->input('message'), 0, 50),\n ]);\n\n if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {\n return $featureCheck;\n }\n\n try {\n $inputData = $request->validated();\n\n $requestData = [\n 'userQuestion' => $inputData['message'],\n 'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),\n 'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),\n ];\n\n $teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());\n if ($teamAiContext?->getPrompt() !== null) {\n $requestData['teamAiContext'] = $teamAiContext->getPrompt();\n }\n\n $this->historyService->appendToUserHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $inputData['message']\n );\n\n $this->historyService->appendToEventHistory(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n type: HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $streamRequest = StreamRequest::onDemandLevel($requestData);\n\n // Track active stream in Redis\n $this->activeStreamsRepository->start(\n $user->getId(),\n $streamRequest->getId(),\n ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()\n );\n\n return $this->prophetService->getStreamedOrAbortedResponse(\n streamRequest: $streamRequest,\n onCompleted: function (\n string $assistantResponse,\n bool $clientAborted,\n bool $hadError,\n ) use ($user, $streamRequest) {\n // Remove in-progress event\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n // Save to history if backend completed successfully (even if client disconnected)\n // Only skip saving if there was an actual error during streaming\n if (! $hadError && ! empty(trim($assistantResponse))) {\n $this->historyService->appendToSystemHistory(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n $assistantResponse,\n );\n }\n\n // Notify frontend if client disconnected (so it can update UI if still on page)\n if ($clientAborted) {\n $this->eventDispatcher->dispatch(\n new AskAnythingAbortedChatCompleted(\n user: $user,\n identifier: HistoryService::ON_DEMAND_SERVICE,\n response: $assistantResponse,\n )\n );\n }\n\n // Remove active stream in Redis\n $this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());\n }\n );\n } catch (Exception $e) {\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n $this->logger->error('Failed to process Ask Anything request', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'question' => $request->input('message'),\n ]);\n\n return new JsonResponse([\n 'error' => 'Failed to process your question',\n ], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);\n }\n }\n\n public function stopStream(Request $request): JsonResponse\n {\n $user = $request->user();\n\n $this->activeStreamsRepository->stopByUser($user->getId());\n\n $this->historyService->removeLastEventMessageByType(\n $user,\n HistoryService::ON_DEMAND_SERVICE,\n HistoryService::EVENT_IN_PROGRESS_TYPE\n );\n\n return response()->json(['message' => 'Stream marked as stopped by user']);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
2033549508898738106
|
-5824280404149966240
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
activitySearch
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
1/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
1
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Validation\ValidationException;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Component\AskAnything\HistoryService;
use Jiminny\Component\AskJiminnyAi\Exceptions\AskJiminnyException;
use Jiminny\Component\AskJiminnyAi\OnDemandLevel\Events\AskAnythingAbortedChatCompleted;
use Jiminny\Component\Prophet\ProphetService;
use Jiminny\Component\ProphetAi\StreamRequest;
use Jiminny\Events\EventDispatcher;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Requests\API\V2\OnDemandAskAnythingRequest;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\User;
use Jiminny\Repositories\ActiveStreamsRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamAiContextRepository;
use Jiminny\Utils\FilterNormalizer;
use Jiminny\VO;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use Symfony\Component\HttpFoundation\StreamedResponse;
class OnDemandV2Controller extends Controller
{
use AuthorizesRequests;
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array FILTER_KEY_EXCLUDED_PARAMS = [
'sequence_number',
'page',
'per_page',
'limit',
'offset',
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly HistoryService $historyService,
private readonly ProphetService $prophetService,
private readonly TeamAiContextRepository $teamAiContextRepository,
private readonly ActiveStreamsRepository $activeStreamsRepository,
private readonly EventDispatcher $eventDispatcher,
private readonly LoggerInterface $logger,
) {
}
/**
* Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled
*/
private function checkAskJiminnyOnAnythingFeature(User $user): ?JsonResponse
{
if (! $user->team->hasFeature(FeatureEnum::ASK_JIMINNY_ON_ANYTHING)) {
return new JsonResponse([
'message' => 'Feature ASK_JIMINNY_ON_ANYTHING is not enabled for this team',
], ResponseAlias::HTTP_FORBIDDEN);
}
return null;
}
/**
* Get top N activity IDs for Ask Jiminny feature based on filters
*
* @throws ValidationException
* @throws ActivityProviderException
*/
public function getContextForAskAnythingByFilter(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
$topCount = $request->input('top_count', self::DEFAULT_TOP_ACTIVITIES_COUNT);
try {
// Always fetch first N (top count) IDs
$onDemandActivitySearchCriteria = VO\Repository\OnDemandActivitySearch\Criteria::createFromRequest(
array_merge($request->all(), ['limit' => $topCount, 'page' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($onDemandActivitySearchCriteria, $user);
$validationRules = $filterSet->getValidationRules()
->merge([
'exclude' => 'array',
'limit' => 'integer|min:1|max:' . $topCount,
])
->all();
$request->validate($validationRules);
$hasChangedFilters = $this->hasChangedContextFilter($request, $user);
$activityIds = $repository->onDemandSearchIdsOnly($user, $onDemandActivitySearchCriteria, $filterSet);
$this->historyService->storeContextIds($user, HistoryService::CONTEXT_IDS, $activityIds);
return new JsonResponse([
'count' => count($activityIds),
'changed_context_filters' => $hasChangedFilters,
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch activity IDs for Ask Jiminny', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'ids' => [],
'error' => 'Failed to fetch activity IDs',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function hasChangedContextFilter(Request $request, User $user): bool
{
$filterKey = $this->makeFilterKey($request);
$result = $this->historyService->compareAndSetFilterKeyWithHistory($user, $filterKey);
if (! $result['changed']) {
return false;
}
if ($result['matches_previous']) {
return false;
}
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
// If no history or last event already matches, return false
if (empty($history) || $this->historyService->hasFilteredChangedEventAsLastMessage($history)) {
return false;
}
// Append event and notify
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_FILTERS_CHANGED_TYPE
);
return true;
}
private function makeFilterKey(Request $request): string
{
$filters = $request->except(self::FILTER_KEY_EXCLUDED_PARAMS);
try {
$normalizedFilters = FilterNormalizer::normalizeFilters($filters);
$json = json_encode(
$normalizedFilters,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);
return hash('xxh3', $json);
} catch (\JsonException $e) {
$this->logger->error('Failed to encode filters', [
'error' => $e->getMessage(),
'filters_keys' => array_keys($filters),
]);
throw new AskJiminnyException('Failed to create filter key', 0, $e);
}
}
/**
* Get Ask Anything conversation history
*/
public function getAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$history = $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse($history, ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to fetch Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'history' => [],
'error' => 'Failed to fetch history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete Ask Anything conversation history
*/
public function deleteAskAnythingHistory(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$this->historyService->deleteHistory($user, HistoryService::ON_DEMAND_SERVICE);
return new JsonResponse([
'message' => 'History deleted successfully',
], ResponseAlias::HTTP_OK);
} catch (Exception $e) {
$this->logger->error('Failed to delete Ask Anything history', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse([
'error' => 'Failed to delete history',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Ask Anything - submit question and get AI response
*/
public function askAnything(OnDemandAskAnythingRequest $request): StreamedResponse|JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->logger->info('AskAnything request received', [
'user_id' => $user->getId(),
'team_id' => $user->getTeamId(),
'request_hash' => md5($request->input('message') . $user->getId() . floor(time() / 60)),
'message_preview' => mb_substr($request->input('message'), 0, 50),
]);
if ($featureCheck = $this->checkAskJiminnyOnAnythingFeature($user)) {
return $featureCheck;
}
try {
$inputData = $request->validated();
$requestData = [
'userQuestion' => $inputData['message'],
'callIds' => $this->historyService->getContextIds($user, HistoryService::CONTEXT_IDS),
'history' => $this->historyService->getHistory($user, HistoryService::ON_DEMAND_SERVICE),
];
$teamAiContext = $this->teamAiContextRepository->getByTeamId($user->getTeamId());
if ($teamAiContext?->getPrompt() !== null) {
$requestData['teamAiContext'] = $teamAiContext->getPrompt();
}
$this->historyService->appendToUserHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$inputData['message']
);
$this->historyService->appendToEventHistory(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
type: HistoryService::EVENT_IN_PROGRESS_TYPE
);
$streamRequest = StreamRequest::onDemandLevel($requestData);
// Track active stream in Redis
$this->activeStreamsRepository->start(
$user->getId(),
$streamRequest->getId(),
ttlSeconds: $streamRequest->getConnectTimeout() + $streamRequest->getReadTimeout()
);
return $this->prophetService->getStreamedOrAbortedResponse(
streamRequest: $streamRequest,
onCompleted: function (
string $assistantResponse,
bool $clientAborted,
bool $hadError,
) use ($user, $streamRequest) {
// Remove in-progress event
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
// Save to history if backend completed successfully (even if client disconnected)
// Only skip saving if there was an actual error during streaming
if (! $hadError && ! empty(trim($assistantResponse))) {
$this->historyService->appendToSystemHistory(
$user,
HistoryService::ON_DEMAND_SERVICE,
$assistantResponse,
);
}
// Notify frontend if client disconnected (so it can update UI if still on page)
if ($clientAborted) {
$this->eventDispatcher->dispatch(
new AskAnythingAbortedChatCompleted(
user: $user,
identifier: HistoryService::ON_DEMAND_SERVICE,
response: $assistantResponse,
)
);
}
// Remove active stream in Redis
$this->activeStreamsRepository->stop($user->getId(), $streamRequest->getId());
}
);
} catch (Exception $e) {
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
$this->logger->error('Failed to process Ask Anything request', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'question' => $request->input('message'),
]);
return new JsonResponse([
'error' => 'Failed to process your question',
], ResponseAlias::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function stopStream(Request $request): JsonResponse
{
$user = $request->user();
$this->activeStreamsRepository->stopByUser($user->getId());
$this->historyService->removeLastEventMessageByType(
$user,
HistoryService::ON_DEMAND_SERVICE,
HistoryService::EVENT_IN_PROGRESS_TYPE
);
return response()->json(['message' => 'Stream marked as stopped by user']);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11122
|
|
11127
|
219
|
54
|
2026-04-14T09:14:06.135856+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158046135_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php(C) PropagateCoachingFee© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsD Themes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.phpCc W .*© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpactivitySearch2.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikKovalik2.10.25KOVallKI<?phpA1X2 A Vdeclare(strict_types=1);mnamesoace Jalmnny htte controulens Ar> use ...class Automacedкeрortskepo o:A15 X4 ^61931141151161171181191211124123L.lU.Lonovallk2.10.25novallk2.10.25Kovalik2.10.25Kovalik* Retrieve all standard (non-Ask Jiminny) Mclass OnDemandV2Controller extends Controlleruse AuthorizesRequests;* @param string $sortColumnThe column tc31.10.25 Ivanov* Oparam string $sortDirection The sort dire 2.10.25Kovalikprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J19.12.25Tolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolovprivate const array FILTER_KEY_EXCLUDED_PARAMS| = [sequence_nunber'page','per_page','limit','offset',/*** Retrieve all Ask Liminny reports created2.10.25Kovalik2.10.25Kovalik* Oodrdll usernusenIne user Ynos2.10.25Kovalik* @param string $sortColumnThe column tc 2.10.25Kovalik* Oparam string $sortDirection The sort dire2.10.25KOVallKIzu.ll.zo Ivanov* @return Collection<AutomatedReport>8.10.25novallk*/2.10.25Kovalik14 usages2.10.25Kovalikpublic function getAskJiminnyReportsByUser(2.10.25KovalikUser $user,2.10.25Kovalikstring $sortColumn = 'created_at',17.10.25 Kovalikstring ssorcbirection = "desc"17.10.25 Kovalik): Collection {...}17.10.25 Kovalikpublic function __construct(private readonly ActivitySearch Saprivate readonly HistoryService ShistoryService,privace readonty rropnetservice spropnetservice,privace readonty leamaiconcexckepostcory preamaiconcexckeposicory.orivace readoncy Acclvescreamskepository saccivescrealskepositorvprivate readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,) 1/*** Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled*/Ordo KoVallk2 usagesprivate function buildSortedQuery(string $sor17.10.25 Kovalik2.10.25novallk2.10.25Kovalik* Get all active and enabled reports with ac2.10.25Kovalik2.10.25* @param string $frequency2.10.25Kovalik2.10.25Kovalikonvare Tuncron checkastunnvunanyum norectureluser "user, rusonkescons* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovalik78 gPvpubuic tunccion gecconcexcrorAskanychingbyrilter kequest grequest, ElasulcA23 usagesZ.10.23Kovalikpublic function getActiveReportsByFrequency(s2.10.25Kovalik/** @var User $user */2.10.25KovalikTests passed: 1 (5 minutes ago), 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:05CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifywo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/ drvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest,php --no-coverage 2261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch‹> CodeClaude Sonnet 4.6W Windsurf Teams39:01 26 charsuir-o( 4 spaces...
|
NULL
|
6795392905184043719
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vToolsWindowHelp© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironnc Mureu canzercnanner© PhpApm.php(C) PropagateCoachingFee© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.phpc resto eAcctvrvcimrroy© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.php> D Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> D AiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeamInsightsD Themes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Con© PlaylistController.© PlaylistShareCont© ReportController.php© AutomatedReportsCommand.phpyJiminnyDeouecommana.ong= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]console SlAGiNG© AskJiminnyReportActivityService.phgA console [PROD]© ActivitySearch.pnp© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php >© HistoryService.php© AskJiminnyReportActivityServiceTest.phpCc W .*© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpTIT:(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php• ActivityLogged.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php(C) AutomatedReport.php© UserPilotActivityListener.php(C) AutomatedReportsCallbackService.php© AutomatedReportResult.phpactivitySearch2.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikKovalik2.10.25KOVallKI<?phpA1X2 A Vdeclare(strict_types=1);mnamesoace Jalmnny htte controulens Ar> use ...class Automacedкeрortskepo o:A15 X4 ^61931141151161171181191211124123L.lU.Lonovallk2.10.25novallk2.10.25Kovalik2.10.25Kovalik* Retrieve all standard (non-Ask Jiminny) Mclass OnDemandV2Controller extends Controlleruse AuthorizesRequests;* @param string $sortColumnThe column tc31.10.25 Ivanov* Oparam string $sortDirection The sort dire 2.10.25Kovalikprivate const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...J19.12.25Tolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolov19.12.25 Nikolovprivate const array FILTER_KEY_EXCLUDED_PARAMS| = [sequence_nunber'page','per_page','limit','offset',/*** Retrieve all Ask Liminny reports created2.10.25Kovalik2.10.25Kovalik* Oodrdll usernusenIne user Ynos2.10.25Kovalik* @param string $sortColumnThe column tc 2.10.25Kovalik* Oparam string $sortDirection The sort dire2.10.25KOVallKIzu.ll.zo Ivanov* @return Collection<AutomatedReport>8.10.25novallk*/2.10.25Kovalik14 usages2.10.25Kovalikpublic function getAskJiminnyReportsByUser(2.10.25KovalikUser $user,2.10.25Kovalikstring $sortColumn = 'created_at',17.10.25 Kovalikstring ssorcbirection = "desc"17.10.25 Kovalik): Collection {...}17.10.25 Kovalikpublic function __construct(private readonly ActivitySearch Saprivate readonly HistoryService ShistoryService,privace readonty rropnetservice spropnetservice,privace readonty leamaiconcexckepostcory preamaiconcexckeposicory.orivace readoncy Acclvescreamskepository saccivescrealskepositorvprivate readonly EventDispatcher $eventDispatcher,private readonly LoggerInterface $logger,) 1/*** Check if the user's team has the ASK_JIMINNY_ON_ANYTHING feature enabled*/Ordo KoVallk2 usagesprivate function buildSortedQuery(string $sor17.10.25 Kovalik2.10.25novallk2.10.25Kovalik* Get all active and enabled reports with ac2.10.25Kovalik2.10.25* @param string $frequency2.10.25Kovalik2.10.25Kovalikonvare Tuncron checkastunnvunanyum norectureluser "user, rusonkescons* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* Othrows ActivityProviderException* dreturh coLcectzon<aucomacedкeрort>2.10.25Kovalik78 gPvpubuic tunccion gecconcexcrorAskanychingbyrilter kequest grequest, ElasulcA23 usagesZ.10.23Kovalikpublic function getActiveReportsByFrequency(s2.10.25Kovalik/** @var User $user */2.10.25KovalikTests passed: 1 (5 minutes ago), 0lablf Support Daily • in 2h 46 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:14:05CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Now let's run the test to verifywo desker nxe dovkcrs/ko3k Automwa/wports/arman yRgportActzvityserväceTest-php --no-coverageloul nor oen ndlr Tler var wi nunbarusanCommand dockerdoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest. php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker vand ioash -d"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisan• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"/home/jiminny/artisan"cd /homee/jiminny && php artisan testtests/nxt/ drvicrs/K2psk/Autonat e"Reports/A3kiminnyReportActivatyserviceTest,php --no-coverage 2261"PASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestfiltersemoty when no resultsE tatt tnt hperiod date filtersids bassess snazero fsequence number to disable first ._. 0.025All 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:ActivityDurationRange → min_duration = 1 (filters out 0-second activities)ActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filtelThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturned O.Fix: AskJiminnyReportActivityService.php:51—added 'sequence_number' » 1 to the Criteria::createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:1cylasPassesNonzerosequencenumberloDisablerarsckequestberaulus assers that the captured uriteria ob ect nas 1srirstRequest() === false.Öul ..Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept allExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch‹> CodeClaude Sonnet 4.6W Windsurf Teams39:01 26 charsuir-o( 4 spaces...
|
11125
|
|
11132
|
221
|
1
|
2026-04-14T09:14:14.641706+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158054641_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpyJiminnyDeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 46 mA100% C•Tue 14 Apr 12:14:14AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeaminsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Cor© PlaylistController.© PlaylistShareContTests passed: 1 (5 minutes ago)= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.phpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..OnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpFILIER KEY EXCLUDED PARAMScc w .*TIT:class OnDemandV2Controller extends ControllerA1X2^private function checkAskJiminnyOnAnythingFeature(User $user): ?Jsonkespons/**Now let's run the test to verifvw(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:B15 V.4 ^2.10.25WlU.co novalik17.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikKovalik4.10.40Kovallk78 Qg >L.lU.LOnovallk 140desker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coveragecould not open input Tile: /var/www/ncml/artisan6162931141151161171181191211124123* Retrieve all standard (non-Ask Jiminny) M7.10.25Kovalik 1277.10.25 Kovalik 157* @param string $sortColumnThe column tc* @param string $sortDirection The sort dire7.10.25Kovalik1587.10.25Kovalik* @return Collection<AutomatedReport>15919.12.25 Nikolov16012 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**10.5Kovalik161Kovalik1621/.l0.zo Kovallk1637.10.25Kovalik1647.10.25Kovalik1657.10.25Kovalik1667.10.25Kovalik1677.10.25Kovalik168* Retrieve all Ask Liminny reports created7.10.25Kovalik169* Oodrdll usernusenIne user Ynos7.10.25Kovalik1707.10.25Kovalik* @param string $sortColumnThe column to171* Oparam string $sortDirection The sort dire10.5KovalikKovalikKovalik* @return Collection<AutomatedReport>7.10.25Kovallk*/9.10.2514 usages7.10.25novallkpublic function getAskJiminnyReportsByUser(7.10.25KovalikUser $user,7.10.25Kovalik179string $sortColumn = 'created_at',7.10.25180string ssorcbirection = "desc"): Collection {...J2.10.25Kovalik1812.10.25Kovalik1822 usagesZ.10.23Kovalik183private function buildSortedQuery(string $sorKovalik184k/**2.10.25KovallkZ0d2.10.25* Get all active and enabled reports with acKovallk2092.10.25novallkL102.10.25Kovalik* @param string $frequency2.10.25Kovalik212 (kg >* dreturh coLcectzon<aucomacedкeрort>23 usages2.10.25Kovalik2372.10.25Kovalik238public function getActiveReportsByFrequency(s2.10.25Kovalik2392.10.25Kovalik248* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* lochrows AcuIvityProv1derexcept1onpublic function getContextForAskAnythingByFilter(Request $request, ElasticACommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker lano oash—e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanprivate function hasChangedContextFilter(Request $request, User $user): booCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"prävate functzon makerziterkey (Request Srequest): stringCascade &e TIiminny/artisanCommand 281sfiltens = Srequest-Bexcept( keys: self::FIILTER KEYL EXCLUDED .PARAMSD ;iminny && php artisan testtests/ext/ drvicrs/K2psk/Autonat eReports/A5KDiman ReportActivatyServiceTest,php --no-coverage 261"$normalizedFilters = FilterNormalizer: :normalizeFilters($filters);$json = json_encode($normalizedFilters,flags: JSON_UNESCAPED_SLASHES/ JSON_UNESCAPED_UNICODE | JSON_THPASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturnsa fittersemoty when no results):get activityget activityE tatt tnt hperiod date filtersr get activityids bassess snazer fsequence number to disable first _ 0.025return hash(algo:"xxh3', $json);} catch (\JsonException $e) {$this->logger-›error('Failed to encode filters', ["error => se->gechessage),'filters_keys'→ array kevs oruters1):throw new AskJiminnyException( message: 'Failed to create filter key* Get Ask Anything conversation historyAll 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51 - added 'sequence_number' = 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Öul ..public function getAskAnythingHistory(Request $request): JsonResponsef...}/*** Delete Ask Anything conversation history*/public function deleteAskAnythingHistory(Request $request): JsonResponse{../**Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept all* Ask Anything - submit question and get AI responseExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6Winasun leams160:09 2o charsuir-o( 4 spaces...
|
NULL
|
-3241878322099472215
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorToo PhpStormFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v© ReportController.phpyJiminnyDeouecommana.ong© AutomatedReportsCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php, 0lablf Support Daily • in 2h 46 mA100% C•Tue 14 Apr 12:14:14AskJiminnyReportActivityServiceT…Defaults© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComm© MakeSlackLiveCoachins© ManageScimForTeam.p(c Malkoanchrorenvironn(C) Mute@raanizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesComiC RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgesi© RemoveUnusedParticip:© ResetElasticsearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© SeedActivities.php© SyncActivity.php©Tracklmported.php© UpdateActivitiesAverag© WhichWorkerlsWorkingr> D Scheduling© Kernel.phpM Contracts> M Domain> MDTO> M Emails› _ Enums> D Events> D Exceptions> DJ FFMpeg>D Formats› D Guards> D Helpersv UHttp> @ AccessTokenProviderv D ControllersV DAPI> DAiCallScoringAiReports> D Deallnsights> D Opportunity> C Page> • Scorecards> D SettingsTeaminsightsnemes> MUserAutomatedRepov DV2C ACIMINVACOnTOAskAnythingCont© AskJiminnyReporl© DealsV2Controlle:© OnDemandV2Cor© PlaylistController.© PlaylistShareContTests passed: 1 (5 minutes ago)= custom.log< console LUl= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]console SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.phpCascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..OnDemandV2Controller.php x© HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpFILIER KEY EXCLUDED PARAMScc w .*TIT:class OnDemandV2Controller extends ControllerA1X2^private function checkAskJiminnyOnAnythingFeature(User $user): ?Jsonkespons/**Now let's run the test to verifvw(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.php(C) AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:B15 V.4 ^2.10.25WlU.co novalik17.10.25 Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25Kovalik2.10.25KovalikKovalik4.10.40Kovallk78 Qg >L.lU.LOnovallk 140desker nte/ sockces/k.osk/AuPowar/orts/artman yeportActivityserviceTest.php --no-coveragecould not open input Tile: /var/www/ncml/artisan6162931141151161171181191211124123* Retrieve all standard (non-Ask Jiminny) M7.10.25Kovalik 1277.10.25 Kovalik 157* @param string $sortColumnThe column tc* @param string $sortDirection The sort dire7.10.25Kovalik1587.10.25Kovalik* @return Collection<AutomatedReport>15919.12.25 Nikolov16012 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/**10.5Kovalik161Kovalik1621/.l0.zo Kovallk1637.10.25Kovalik1647.10.25Kovalik1657.10.25Kovalik1667.10.25Kovalik1677.10.25Kovalik168* Retrieve all Ask Liminny reports created7.10.25Kovalik169* Oodrdll usernusenIne user Ynos7.10.25Kovalik1707.10.25Kovalik* @param string $sortColumnThe column to171* Oparam string $sortDirection The sort dire10.5KovalikKovalikKovalik* @return Collection<AutomatedReport>7.10.25Kovallk*/9.10.2514 usages7.10.25novallkpublic function getAskJiminnyReportsByUser(7.10.25KovalikUser $user,7.10.25Kovalik179string $sortColumn = 'created_at',7.10.25180string ssorcbirection = "desc"): Collection {...J2.10.25Kovalik1812.10.25Kovalik1822 usagesZ.10.23Kovalik183private function buildSortedQuery(string $sorKovalik184k/**2.10.25KovallkZ0d2.10.25* Get all active and enabled reports with acKovallk2092.10.25novallkL102.10.25Kovalik* @param string $frequency2.10.25Kovalik212 (kg >* dreturh coLcectzon<aucomacedкeрort>23 usages2.10.25Kovalik2372.10.25Kovalik238public function getActiveReportsByFrequency(s2.10.25Kovalik2392.10.25Kovalik248* Get top N activity IDs for Ask Jiminny feature based on filters* Othrows ValidationException* lochrows AcuIvityProv1derexcept1onpublic function getContextForAskAnythingByFilter(Request $request, ElasticACommand dockeldoster nxe ceockes /kJosk/AuP /ape/a/poras/A5kJ1minyReportActivityServiceTest.php --no-coverageCould not open input file: /app/artisanCommand dockeroocker exec oocker lano oash—e"cd /var/www&& php artisan testLests unlu services Klosk Aucomaceakeporcs AskJiminnykeportAccivityservicelest.ono =-no-coverade D&l'Could not open input file: artisanprivate function hasChangedContextFilter(Request $request, User $user): booCommand docken• docker exec docker_lamp_1 bash -c "find / -name artisan -maxdepth 6 2>/dev/null | head -5"prävate functzon makerziterkey (Request Srequest): stringCascade &e TIiminny/artisanCommand 281sfiltens = Srequest-Bexcept( keys: self::FIILTER KEYL EXCLUDED .PARAMSD ;iminny && php artisan testtests/ext/ drvicrs/K2psk/Autonat eReports/A5KDiman ReportActivatyServiceTest,php --no-coverage 261"$normalizedFilters = FilterNormalizer: :normalizeFilters($filters);$json = json_encode($normalizedFilters,flags: JSON_UNESCAPED_SLASHES/ JSON_UNESCAPED_UNICODE | JSON_THPASSgetTests\Unit\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityServiceTestreturnsa fittersemoty when no results):get activityget activityE tatt tnt hperiod date filtersr get activityids bassess snazer fsequence number to disable first _ 0.025return hash(algo:"xxh3', $json);} catch (\JsonException $e) {$this->logger-›error('Failed to encode filters', ["error => se->gechessage),'filters_keys'→ array kevs oruters1):throw new AskJiminnyException( message: 'Failed to create filter key* Get Ask Anything conversation historyAll 8 tests pass. Here's a summary:Root Cause & FixRoot cause: buildRequestParamsFromSearch never set sequence number in the request params, so Criteria::createFromRequest defaulted it to 0Since isFirstRequest() returns true when sequenceNumber === 0, several implicit defaults were silently applied:Activitvourat ionRande → min duration = 1 Tilters ouf o-second activitiesiActivityRecorded → only_recorded = 1 (restricts to recorded activities only)OrganiserGroupIn → applies user's default group as a filterThe frontend URL you noticed uses sequence_number=4, which disables these defaults - explaining why the frontend returned activities but the servicereturee o.Fix: AskJiminnyReportActivityService.php:51 - added 'sequence_number' = 1 to the Criteria:: createFromRequest merge, ensuring isFirstRequest() returns false and no implicit defaults are injected.Test added: testGetAct:/cylasPassesnonzerosequencenumberlobisablerarsckequestberaulus asserts that the captured uriterla oblect nas 1srirstRequest() === false.Öul ..public function getAskAnythingHistory(Request $request): JsonResponsef...}/*** Delete Ask Anything conversation history*/public function deleteAskAnythingHistory(Request $request): JsonResponse{../**Vew allliItlle wiun changesvapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Reject allAccept all* Ask Anything - submit question and get AI responseExplain it to me again. Why is there issue with that? Where is it expected and why do l need to work with that. How is it used [EMAIL] | am trying to fetch the activities based on savedSearch<>CodeClaude Sonnet 4.6Winasun leams160:09 2o charsuir-o( 4 spaces...
|
NULL
|
|
11144
|
221
|
7
|
2026-04-14T09:14:49.104776+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158089104_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8563436494813991353
|
-5967358188006330764
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
|
11145
|
221
|
8
|
2026-04-14T09:14:55.156439+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158095156_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php©RoleChangeEventRepositol© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReportsD AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(0 TrackProviderinstalled-vent.onv© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ V 395859114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m 43* @param string $sortColumnThe column to44* @param string $sortDirection The sort dire 45* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column toi* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/—6214 usagespublic function getAskJiminnyReportsByUser(- 64User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor]— 68-71/*** Get all active and enabled reports with al* @param string $frequency— 76* dreturn coccectron<aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© OnDemandV2Controller.php© HistoryService.phpAskJiminnykeportAcuivilyservice.ong xActiviysearch.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace conscraint is applled - macching che denavaour of geccontexchoraskanychingbyralce* Oreturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {Cascade & TICommand 9l$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);ocrurerta = urluerta.:creocerronkequestAcceptmagee ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('lAskviminnxReport] Fetchedactivity IDs for saved search', ["saveo scalrcin 10=nsaveosearci-poetlo'user id' => Suser->getido'activity_count' => count($activityIds),1):return $activityIds;Extract Surround I/ Eonivate tuncrion outuoreduestrarans-ronsearchsearch savedsearch. user "user): arrav$params = 1:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValve();if (in_array($key,continue;haystack: self::DATE_FILTER_KEYS,strict: true)) &X Reject File 0* €halSupport Daily • in 2h 46 mAU AskJiminnyReportActivityServiceT..Defaults100% [2Tue 14 Apr 12:14:54CascadeFixing ReportControllerAutomated Report M: XC Fixing Ask Jiminny R+D ...pected and why do I need to work with that. How is it used inConkSiminyCeporo/tavtyS ervite, hto tetch t shotiftie saseased on savedSearch. THe ids in on demand and inExploring.Itlle wiun changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> CodeClaude Sonnet 4.6Reject allView allAccept allW Windsurf Teamsb6:6895 chars, 22 line breaksuir-o( 4 spaces...
|
NULL
|
9183449782414629797
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFV faVsco.jsProject vEditViewNavigateC PhpStormFileFV faVsco.jsProject vEditViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php©RoleChangeEventRepositol© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReportsD AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (5 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(0 TrackProviderinstalled-vent.onv© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 ^ V 395859114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m 43* @param string $sortColumnThe column to44* @param string $sortDirection The sort dire 45* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A* Oodrdll usernusenIne user Ynos* @param string $sortColumnThe column toi* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/—6214 usagespublic function getAskJiminnyReportsByUser(- 64User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor]— 68-71/*** Get all active and enabled reports with al* @param string $frequency— 76* dreturn coccectron<aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNG© OnDemandV2Controller.php© HistoryService.phpAskJiminnykeportAcuivilyservice.ong xActiviysearch.php© Criteria.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace conscraint is applled - macching che denavaour of geccontexchoraskanychingbyralce* Oreturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {Cascade & TICommand 9l$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);ocrurerta = urluerta.:creocerronkequestAcceptmagee ($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('lAskviminnxReport] Fetchedactivity IDs for saved search', ["saveo scalrcin 10=nsaveosearci-poetlo'user id' => Suser->getido'activity_count' => count($activityIds),1):return $activityIds;Extract Surround I/ Eonivate tuncrion outuoreduestrarans-ronsearchsearch savedsearch. user "user): arrav$params = 1:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValve();if (in_array($key,continue;haystack: self::DATE_FILTER_KEYS,strict: true)) &X Reject File 0* €halSupport Daily • in 2h 46 mAU AskJiminnyReportActivityServiceT..Defaults100% [2Tue 14 Apr 12:14:54CascadeFixing ReportControllerAutomated Report M: XC Fixing Ask Jiminny R+D ...pected and why do I need to work with that. How is it used inConkSiminyCeporo/tavtyS ervite, hto tetch t shotiftie saseased on savedSearch. THe ids in on demand and inExploring.Itlle wiun changes vapp/Services/Kiosk/AutomatedReports/D AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> CodeClaude Sonnet 4.6Reject allView allAccept allW Windsurf Teamsb6:6895 chars, 22 line breaksuir-o( 4 spaces...
|
11144
|