|
1596
|
64
|
24
|
2026-05-07T09:00:49.592452+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778144449592_m2.jpg...
|
Slack
|
Toast (DM) - Jiminny Inc - 3 new items - Slack
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
All, 4 unread
DMs
Add new tab
Reminder
DM
Reschedule
Mark as read
Clear
More actions
Stoyan Tanev:
Здрасти, за този тикет:
[URL_WITH_CREDENTIALS] Ivanov
@Nikolay Ivanov
transitioned a Bug you are watching from
Code Review
⟶
Deployed
…
Wednesday, April 29th
Aneliya Angelova
Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev
Apr 29th
да
Stoyan Tanev
DM
Apr 29th
трябва ли да синкваме нещо от наша страна?
Tuesday, April 28th
Stefka Stoyanova
Thread
Apr 28th
тия тикети е добре да влезнат в другия спринт ли? сложете някакви естимейти тогава
Ves
Thread in
DM
:
исках да те питам credentials на AWS. Направих server на постмарк за QAI но не знам как да добавя key, май вече не е през env. Има ли някакви инструкции?
Apr 28th
смени го в Circle CI env на новия токен който си направил
Home
Messages
Messages
About
Jump to date
Toast
APP
May 5th at 10:00:03 AM
10:00 AM
Review
prophet
#493 JY-20566: Re-eval action items
#493 JY-20566: Re-eval action items
17 hours old・22 files changed・
@Steliyan Georgiev
@Steliyan Georgiev
Added by
Toast for GitHub
Toast for GitHub
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
6 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
Jump to date
Toast
APP
Yesterday at 10:00:03 AM
10:00 AM
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
7 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
New
Toast
APP
Today at 10:00:02 AM
10:00 AM
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
8 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Channel...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.0056515955,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"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.0029920214,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"bounds":{"left":0.0066489363,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.0029920214,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.0076462766,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"bounds":{"left":0.0029920214,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"bounds":{"left":0.004986702,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.005319149,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.0076462766,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"bounds":{"left":0.0029920214,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.0076462766,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.007978723,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.009973404,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"bounds":{"left":0.0029920214,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.00731383,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.00731383,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.00930851,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"bounds":{"left":0.0029920214,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.006981383,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.00731383,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.010638298,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"All, 4 unread","depth":19,"bounds":{"left":0.028922873,"top":0.09497207,"width":0.021276595,"height":0.026336791},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"DMs","depth":19,"bounds":{"left":0.050199468,"top":0.09497207,"width":0.01462766,"height":0.026336791},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Add new tab","depth":20,"bounds":{"left":0.0674867,"top":0.09497207,"width":0.005319149,"height":0.026336791},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reminder","depth":22,"bounds":{"left":0.047872342,"top":0.18276137,"width":0.021609042,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.047872342,"top":0.18276137,"width":0.0033244682,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.05119681,"top":0.18276137,"width":0.018284574,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"DM","depth":22,"bounds":{"left":0.047872342,"top":0.19952115,"width":0.00731383,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Reschedule","depth":23,"bounds":{"left":0.0774601,"top":0.17797287,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mark as read","depth":23,"bounds":{"left":0.08809841,"top":0.17797287,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Clear","depth":23,"bounds":{"left":0.0987367,"top":0.17797287,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":23,"bounds":{"left":0.109375,"top":0.17797287,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Stoyan Tanev:","depth":23,"bounds":{"left":0.03324468,"top":0.21787709,"width":0.03125,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03324468,"top":0.21787709,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.035904255,"top":0.21787709,"width":0.027593086,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Здрасти, за този тикет:","depth":23,"bounds":{"left":0.064494684,"top":0.21787709,"width":0.05319149,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.064494684,"top":0.21787709,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":22,"bounds":{"left":0.06715426,"top":0.21787709,"width":0.050531916,"height":0.014365523}}],"role_description":"text"},{"role":"AXLink","text":"https://jiminny.atlassian.net/browse/SRD-6793","depth":23,"bounds":{"left":0.03324468,"top":0.23543495,"width":0.08577128,"height":0.031923383},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"https://jiminny.atlassian.net/browse/SRD-6793","depth":24,"bounds":{"left":0.03324468,"top":0.23543495,"width":0.08577128,"height":0.031923383},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03324468,"top":0.23543495,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":44,"bounds":{"left":0.03324468,"top":0.23543495,"width":0.08610372,"height":0.031923383}}],"role_description":"text"},{"role":"AXButton","text":"Mark complete","depth":23,"bounds":{"left":0.03324468,"top":0.2434158,"width":0.04255319,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reminder","depth":22,"bounds":{"left":0.047872342,"top":0.29449323,"width":0.021609042,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.047872342,"top":0.29449323,"width":0.0033244682,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.05119681,"top":0.29449323,"width":0.018284574,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Post in","depth":22,"bounds":{"left":0.047872342,"top":0.31125298,"width":0.013297873,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.047872342,"top":0.31125298,"width":0.0026595744,"height":0.012769354}},{"char_start":1,"char_count":6,"bounds":{"left":0.050531916,"top":0.31125298,"width":0.010638298,"height":0.012769354}}],"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":22,"bounds":{"left":0.062832445,"top":0.32881084,"width":0.00831117,"height":0.02952913},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.06781915,"top":0.3120511,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":6,"bounds":{"left":0.0631649,"top":0.32960895,"width":0.00831117,"height":0.028731046}}],"role_description":"text"},{"role":"AXStaticText","text":"Incomplete","depth":22,"bounds":{"left":0.073803194,"top":0.29688746,"width":0.019614361,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.07413564,"top":0.29688746,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.07513298,"top":0.29688746,"width":0.01861702,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Just now","depth":22,"bounds":{"left":0.102726065,"top":0.29608938,"width":0.017287234,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.102726065,"top":0.29608938,"width":0.0019946808,"height":0.013567438}},{"char_start":1,"char_count":7,"bounds":{"left":0.10472074,"top":0.29608938,"width":0.015292553,"height":0.013567438}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov:","depth":23,"bounds":{"left":0.03324468,"top":0.32960895,"width":0.034574468,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03324468,"top":0.32960895,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.03723404,"top":0.32960895,"width":0.02925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"For those using","depth":23,"bounds":{"left":0.0674867,"top":0.32960895,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.06781915,"top":0.32960895,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.07047872,"top":0.32960895,"width":0.030917553,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"make cs-fix","depth":24,"bounds":{"left":0.03324468,"top":0.32960895,"width":0.08610372,"height":0.031923383},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"and getting annoyed by how long it takes (since it scans the entire project), you can now use","depth":23,"bounds":{"left":0.03324468,"top":0.3471668,"width":0.08577128,"height":0.040702313},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.04654255,"top":0.3471668,"width":0.0016622341,"height":0.014365523}},{"char_start":1,"char_count":92,"bounds":{"left":0.03324468,"top":0.3471668,"width":0.08577128,"height":0.049481247}}],"role_description":"text"},{"role":"AXStaticText","text":"make cs-fix-branch","depth":24,"bounds":{"left":0.03324468,"top":0.38467678,"width":0.08510638,"height":0.0031923384},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":". It will fix only the files that differ from","depth":23,"bounds":{"left":0.03324468,"top":0.38707104,"width":0.08643617,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"master","depth":24,"bounds":{"left":0.039893616,"top":0.38707104,"width":0.014295213,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":", and it runs in just a couple of seconds","depth":23,"bounds":{"left":0.03324468,"top":0.38707104,"width":0.08610372,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Mark complete","depth":23,"bounds":{"left":0.03324468,"top":0.35514766,"width":0.04255319,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast","depth":22,"bounds":{"left":0.047872342,"top":0.40622506,"width":0.011635638,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.047872342,"top":0.40622506,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.050199468,"top":0.40622506,"width":0.00930851,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"App","depth":22,"bounds":{"left":0.047872342,"top":0.42298484,"width":0.0076462766,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.047872342,"top":0.42298484,"width":0.0029920214,"height":0.012769354}},{"char_start":1,"char_count":2,"bounds":{"left":0.05086436,"top":0.42298484,"width":0.004986702,"height":0.012769354}}],"role_description":"text"},{"role":"AXButton","text":"Mark as unread","depth":23,"bounds":{"left":0.08809841,"top":0.40143654,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Clear","depth":23,"bounds":{"left":0.0987367,"top":0.40143654,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":23,"bounds":{"left":0.109375,"top":0.40143654,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"[no preview available]","depth":23,"bounds":{"left":0.03324468,"top":0.44134077,"width":0.04720745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03324468,"top":0.44134077,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":21,"bounds":{"left":0.034574468,"top":0.44134077,"width":0.045877658,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Monday, May 4th","depth":21,"bounds":{"left":0.059507977,"top":0.49481246,"width":0.033909574,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.059840426,"top":0.49561054,"width":0.0039893617,"height":0.012769354}},{"char_start":1,"char_count":14,"bounds":{"left":0.06382979,"top":0.49561054,"width":0.029587766,"height":0.012769354}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":22,"bounds":{"left":0.047872342,"top":0.5403033,"width":0.021609042,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.047872342,"top":0.5403033,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.049867023,"top":0.5403033,"width":0.019946808,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"App","depth":22,"bounds":{"left":0.047872342,"top":0.55706304,"width":0.0076462766,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.047872342,"top":0.55706304,"width":0.0029920214,"height":0.012769354}},{"char_start":1,"char_count":2,"bounds":{"left":0.05086436,"top":0.55706304,"width":0.004986702,"height":0.012769354}}],"role_description":"text"},{"role":"AXStaticText","text":"Monday","depth":22,"bounds":{"left":0.1043883,"top":0.54189944,"width":0.015625,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.1043883,"top":0.54189944,"width":0.0043218085,"height":0.012769354}},{"char_start":1,"char_count":5,"bounds":{"left":0.10837766,"top":0.54189944,"width":0.011968086,"height":0.012769354}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"bounds":{"left":0.04055851,"top":0.575419,"width":0.0013297872,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"@Nikolay Ivanov","depth":23,"bounds":{"left":0.04155585,"top":0.5746209,"width":0.03856383,"height":0.015961692},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"@Nikolay Ivanov","depth":24,"bounds":{"left":0.042220745,"top":0.575419,"width":0.03723404,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.04255319,"top":0.575419,"width":0.0043218085,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.04654255,"top":0.575419,"width":0.032912236,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"transitioned a Bug you are watching from","depth":23,"bounds":{"left":0.03324468,"top":0.575419,"width":0.07978723,"height":0.031923383},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.080119684,"top":0.575419,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":39,"bounds":{"left":0.03324468,"top":0.575419,"width":0.080119684,"height":0.031923383}}],"role_description":"text"},{"role":"AXStaticText","text":"Code Review","depth":23,"bounds":{"left":0.03324468,"top":0.59297687,"width":0.07712766,"height":0.031923383},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.09375,"top":0.59297687,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.03324468,"top":0.59297687,"width":0.0774601,"height":0.031923383}}],"role_description":"text"},{"role":"AXStaticText","text":"⟶","depth":23,"bounds":{"left":0.04920213,"top":0.6105347,"width":0.007978723,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Deployed","depth":23,"bounds":{"left":0.056848403,"top":0.6105347,"width":0.021609042,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.05718085,"top":0.6105347,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.060837764,"top":0.6105347,"width":0.01761968,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"…","depth":23,"bounds":{"left":0.078125,"top":0.6105347,"width":0.0039893617,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Wednesday, April 29th","depth":21,"bounds":{"left":0.054521278,"top":0.64644855,"width":0.043882977,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.054853722,"top":0.6472466,"width":0.0043218085,"height":0.012769354}},{"char_start":1,"char_count":20,"bounds":{"left":0.059175532,"top":0.6472466,"width":0.03956117,"height":0.012769354}}],"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":22,"bounds":{"left":0.047872342,"top":0.69193935,"width":0.03756649,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.047872342,"top":0.69193935,"width":0.0033244682,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.05119681,"top":0.69193935,"width":0.034242023,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev","depth":22,"bounds":{"left":0.04920213,"top":0.70790106,"width":0.05086436,"height":0.0015961692},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apr 29th","depth":22,"bounds":{"left":0.10305851,"top":0.6935355,"width":0.016954787,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10305851,"top":0.6935355,"width":0.0033244682,"height":0.012769354}},{"char_start":1,"char_count":7,"bounds":{"left":0.10605053,"top":0.6935355,"width":0.014295213,"height":0.012769354}}],"role_description":"text"},{"role":"AXStaticText","text":"да","depth":23,"bounds":{"left":0.03324468,"top":0.7086991,"width":0.0056515955,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":22,"bounds":{"left":0.047872342,"top":0.7086991,"width":0.028922873,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DM","depth":22,"bounds":{"left":0.047872342,"top":0.7086991,"width":0.00731383,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apr 29th","depth":22,"bounds":{"left":0.10305851,"top":0.7086991,"width":0.016954787,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"трябва ли да синкваме нещо от наша страна?","depth":23,"bounds":{"left":0.03324468,"top":0.7086991,"width":0.07413564,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tuesday, April 28th","depth":21,"bounds":{"left":0.05817819,"top":0.7086991,"width":0.036901597,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":22,"bounds":{"left":0.047872342,"top":0.7086991,"width":0.03756649,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Thread","depth":22,"bounds":{"left":0.047872342,"top":0.7086991,"width":0.013297873,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apr 28th","depth":22,"bounds":{"left":0.10305851,"top":0.7086991,"width":0.016954787,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"тия тикети е добре да влезнат в другия спринт ли? сложете някакви естимейти тогава","depth":23,"bounds":{"left":0.03324468,"top":0.7086991,"width":0.08643617,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":22,"bounds":{"left":0.047872342,"top":0.7086991,"width":0.0076462766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Thread in","depth":22,"bounds":{"left":0.047872342,"top":0.7086991,"width":0.017952127,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.06549202,"top":0.7086991,"width":0.0013297872,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DM","depth":22,"bounds":{"left":0.06648936,"top":0.7086991,"width":0.0076462766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":":","depth":22,"bounds":{"left":0.073803194,"top":0.7086991,"width":0.0023271276,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"исках да те питам credentials на AWS. Направих server на постмарк за QAI но не знам как да добавя key, май вече не е през env. Има ли някакви инструкции?","depth":22,"bounds":{"left":0.047872342,"top":0.7086991,"width":0.05418883,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apr 28th","depth":22,"bounds":{"left":0.10305851,"top":0.7086991,"width":0.016954787,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"смени го в Circle CI env на новия токен който си направил","depth":23,"bounds":{"left":0.03324468,"top":0.7086991,"width":0.075465426,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Home","depth":17,"bounds":{"left":0.13796543,"top":0.09177973,"width":0.011635638,"height":0.028731046},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.15890957,"top":0.09177973,"width":0.018949468,"height":0.028731046},"on_screen":true,"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.15890957,"top":0.09976058,"width":0.018949468,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15890957,"top":0.10055866,"width":0.0043218085,"height":0.012769354}},{"char_start":1,"char_count":7,"bounds":{"left":0.16289894,"top":0.10055866,"width":0.014960106,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"About","depth":17,"bounds":{"left":0.18683511,"top":0.09177973,"width":0.012300532,"height":0.028731046},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Jump to date","depth":24,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Toast","depth":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"APP","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"May 5th at 10:00:03 AM","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:00 AM","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Review","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"prophet","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"#493 JY-20566: Re-eval action items","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#493 JY-20566: Re-eval action items","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"17 hours old・22 files changed・","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"@Steliyan Georgiev","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"@Steliyan Georgiev","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Resolve Conflicts","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"#11443 Test hublets latency","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 Test hublets latency","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"4 months old・20 files changed","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"#11327 JY-19501 webhook based opportunity sync","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 JY-19501 webhook based opportunity sync","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Show more","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Needs Love","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"6 days old・1 file changed","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":24,"bounds":{"left":0.26230052,"top":0.12609737,"width":0.032912236,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Toast","depth":25,"bounds":{"left":0.1512633,"top":0.14764565,"width":0.011968086,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"APP","depth":25,"bounds":{"left":0.16555852,"top":0.15163608,"width":0.0066489363,"height":0.009577015},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"bounds":{"left":0.17287233,"top":0.14924182,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Yesterday at 10:00:03 AM","depth":25,"bounds":{"left":0.17553191,"top":0.15163608,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:00 AM","depth":26,"bounds":{"left":0.17553191,"top":0.15163608,"width":0.01761968,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.17553191,"top":0.15163608,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.17785904,"top":0.15163608,"width":0.015625,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Resolve Conflicts","depth":28,"bounds":{"left":0.15658244,"top":0.16839585,"width":0.038231384,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.16839585,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.15957446,"top":0.16839585,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"bounds":{"left":0.15658244,"top":0.1859537,"width":0.00831117,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.1859537,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.15924202,"top":0.1859537,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXLink","text":"#11443 Test hublets latency","depth":28,"bounds":{"left":0.15658244,"top":0.20351157,"width":0.0625,"height":0.014365523},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 Test hublets latency","depth":29,"bounds":{"left":0.15658244,"top":0.20351157,"width":0.0625,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.20351157,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":26,"bounds":{"left":0.15957446,"top":0.20351157,"width":0.059507977,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"4 months old・20 files changed","depth":28,"bounds":{"left":0.15658244,"top":0.22106944,"width":0.069148935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.22106944,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":28,"bounds":{"left":0.15957446,"top":0.22106944,"width":0.06615692,"height":0.014365523}}],"role_description":"text"},{"role":"AXLink","text":"#11327 JY-19501 webhook based opportunity sync","depth":28,"bounds":{"left":0.15658244,"top":0.24501197,"width":0.11469415,"height":0.014365523},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 JY-19501 webhook based opportunity sync","depth":29,"bounds":{"left":0.15658244,"top":0.24501197,"width":0.11469415,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.24501197,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":45,"bounds":{"left":0.15957446,"top":0.24501197,"width":0.11170213,"height":0.014365523}}],"role_description":"text"},{"role":"AXButton","text":"Show more","depth":27,"bounds":{"left":0.15658244,"top":0.26097366,"width":0.024601065,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Added by","depth":27,"bounds":{"left":0.15658244,"top":0.2849162,"width":0.01761968,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.2849162,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.15924202,"top":0.2849162,"width":0.013962766,"height":0.011971269}}],"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"bounds":{"left":0.17386968,"top":0.2849162,"width":0.02925532,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"bounds":{"left":0.17386968,"top":0.2849162,"width":0.02925532,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.17420213,"top":0.2849162,"width":0.0019946808,"height":0.011971269}},{"char_start":1,"char_count":15,"bounds":{"left":0.17586437,"top":0.2849162,"width":0.027593086,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Needs Love","depth":28,"bounds":{"left":0.15658244,"top":0.3064645,"width":0.025930852,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.3064645,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.16057181,"top":0.3064645,"width":0.021941489,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"bounds":{"left":0.15658244,"top":0.32402235,"width":0.00831117,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.32402235,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.15924202,"top":0.32402235,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXLink","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":28,"bounds":{"left":0.15658244,"top":0.3415802,"width":0.15924202,"height":0.014365523},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":29,"bounds":{"left":0.15658244,"top":0.3415802,"width":0.15924202,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.3415802,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":69,"bounds":{"left":0.15957446,"top":0.3415802,"width":0.15625,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"7 days old・1 file changed","depth":28,"bounds":{"left":0.15658244,"top":0.35913807,"width":0.057513297,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Added by","depth":27,"bounds":{"left":0.15658244,"top":0.38467678,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"bounds":{"left":0.17386968,"top":0.38467678,"width":0.02925532,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"bounds":{"left":0.17386968,"top":0.38467678,"width":0.02925532,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":27,"bounds":{"left":0.33543882,"top":0.1348763,"width":0.010638298,"height":0.025538707},"on_screen":true,"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":27,"bounds":{"left":0.3460771,"top":0.1348763,"width":0.010638298,"height":0.025538707},"on_screen":true,"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":27,"bounds":{"left":0.3567154,"top":0.1348763,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":27,"bounds":{"left":0.36735374,"top":0.1348763,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":27,"bounds":{"left":0.37799203,"top":0.1348763,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":27,"bounds":{"left":0.38863033,"top":0.1348763,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":27,"bounds":{"left":0.39926863,"top":0.1348763,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":27,"bounds":{"left":0.40990692,"top":0.1348763,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Jump to date","depth":24,"bounds":{"left":0.26595744,"top":0.4142059,"width":0.025598405,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New","depth":24,"bounds":{"left":0.41223404,"top":0.41819632,"width":0.008976064,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Toast","depth":25,"bounds":{"left":0.1512633,"top":0.44533122,"width":0.011968086,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"APP","depth":25,"bounds":{"left":0.16555852,"top":0.44932163,"width":0.0066489363,"height":0.009577015},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"bounds":{"left":0.17287233,"top":0.44692737,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 10:00:02 AM","depth":25,"bounds":{"left":0.17553191,"top":0.44932163,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:00 AM","depth":26,"bounds":{"left":0.17553191,"top":0.44932163,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Resolve Conflicts","depth":28,"bounds":{"left":0.15658244,"top":0.4660814,"width":0.038231384,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"bounds":{"left":0.15658244,"top":0.48363927,"width":0.00831117,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#11443 Test hublets latency","depth":28,"bounds":{"left":0.15658244,"top":0.5011971,"width":0.0625,"height":0.014365523},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 Test hublets latency","depth":29,"bounds":{"left":0.15658244,"top":0.5011971,"width":0.0625,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4 months old・20 files changed","depth":28,"bounds":{"left":0.15658244,"top":0.51875496,"width":0.069148935,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#11327 JY-19501 webhook based opportunity sync","depth":28,"bounds":{"left":0.15658244,"top":0.54269755,"width":0.11469415,"height":0.014365523},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 JY-19501 webhook based opportunity sync","depth":29,"bounds":{"left":0.15658244,"top":0.54269755,"width":0.11469415,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Show more","depth":27,"bounds":{"left":0.15658244,"top":0.5586592,"width":0.024601065,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Added by","depth":27,"bounds":{"left":0.15658244,"top":0.5826017,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"bounds":{"left":0.17386968,"top":0.5826017,"width":0.02925532,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"bounds":{"left":0.17386968,"top":0.5826017,"width":0.02925532,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Needs Love","depth":28,"bounds":{"left":0.15658244,"top":0.60415006,"width":0.025930852,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"bounds":{"left":0.15658244,"top":0.6217079,"width":0.00831117,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":28,"bounds":{"left":0.15658244,"top":0.632083,"width":0.15924202,"height":0.0007980846},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":29,"bounds":{"left":0.15658244,"top":0.632083,"width":0.15924202,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"8 days old・1 file changed","depth":28,"bounds":{"left":0.15658244,"top":0.632083,"width":0.057513297,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Added by","depth":27,"bounds":{"left":0.15658244,"top":0.632083,"width":0.01761968,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"bounds":{"left":0.17386968,"top":0.632083,"width":0.02925532,"height":0.0007980846},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"bounds":{"left":0.17386968,"top":0.632083,"width":0.02925532,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":27,"on_screen":false,"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":27,"on_screen":false,"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":27,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":27,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":27,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":24,"bounds":{"left":0.13696809,"top":0.6272945,"width":0.2835771,"height":0.030327214},"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Channel","depth":11,"bounds":{"left":0.0,"top":0.7126895,"width":0.017287234,"height":0.0007980846},"on_screen":true,"role_description":"text"}]...
|
-9097146115657707968
|
-3589467510854988474
|
visual_change
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
All, 4 unread
DMs
Add new tab
Reminder
DM
Reschedule
Mark as read
Clear
More actions
Stoyan Tanev:
Здрасти, за този тикет:
[URL_WITH_CREDENTIALS] Ivanov
@Nikolay Ivanov
transitioned a Bug you are watching from
Code Review
⟶
Deployed
…
Wednesday, April 29th
Aneliya Angelova
Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev
Apr 29th
да
Stoyan Tanev
DM
Apr 29th
трябва ли да синкваме нещо от наша страна?
Tuesday, April 28th
Stefka Stoyanova
Thread
Apr 28th
тия тикети е добре да влезнат в другия спринт ли? сложете някакви естимейти тогава
Ves
Thread in
DM
:
исках да те питам credentials на AWS. Направих server на постмарк за QAI но не знам как да добавя key, май вече не е през env. Има ли някакви инструкции?
Apr 28th
смени го в Circle CI env на новия токен който си направил
Home
Messages
Messages
About
Jump to date
Toast
APP
May 5th at 10:00:03 AM
10:00 AM
Review
prophet
#493 JY-20566: Re-eval action items
#493 JY-20566: Re-eval action items
17 hours old・22 files changed・
@Steliyan Georgiev
@Steliyan Georgiev
Added by
Toast for GitHub
Toast for GitHub
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
6 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
Jump to date
Toast
APP
Yesterday at 10:00:03 AM
10:00 AM
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
7 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
New
Toast
APP
Today at 10:00:02 AM
10:00 AM
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
8 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Channel
HomeDMSslackViewMistonWindowHelpQ Describe what you are looking folAC.MIVAll4DMsReminderstovan lanev: sлрасти, за тами тике....Mark comnleteReminderPost in tIncomplete Just nowNikolay Ivanov: For those using make .../ Mark comnleteÍno preview available'Monday. May 4thn Jira Cloud_@Nikolay Ivanov transitioned aBug you are watching from Code …Wednesday, April 29theAneliya AngelovaAor 29thlUse(C) ChandeEmailJob.oho@ DeactivateUser.Job.ohn(C) Setur DefaultSavedSean© SyncTolntercom.php© SyncToPlanhat.php© SyncToUserPilot.phpC. RaseProceccina.loh.nhnC) Dummv.loh.nhnC ImnortDocallAPocordinas 1© ImportRemoteTrackJob.ph(e.lob.php(e) lohdicnatchor nhnloastHomeMessagesYesterdavToast APP 10:00 AMResolve Conflictsapp#11443 lest hublets latency4 months old • 20 hles changed#11327 JY-19501 webhook based opportunity syncShow moreAdded by Toast for GitHukNeeds love(12024 JY-20773 fix user pilot tracking ofr automated report penerated7 days old • 1 file changedAdded bv Toast for GitHubTodavvToast APP 10:00 AMResolve Confllicts#11443 Test hublets latency4 months oldk• 20 files changed#11327 JY-19501 webhook based onportunity svnc.Show moreAdded by Toast for GitHubNeeds LoveMessage loastAafunction (Activity $activity) use ($dispatcher, $logger, $entityIdField, $crmObject, $emi64)Sstageld = Sactivitv->aetStaae@2->aetIdo1649SloaData =1$crmObject->value => $this->id,'activity' => $activity->getIdO.'emitEvent' => $emitEvent,651652653654SupdateData = [AendsentitvidField =s nult// For leads and opportunities, also nullify the stage idif (Sstageld && in_array(Scrm0biect. [CrmObiect::LEAD. Crm0biect::OPPORTUNITY]suppont Dally • In 3h100% 12Thu 7 May 12:00:49fravel.log4 SF jiminny@localhost]A HS_local (jiminny@localhost]« console [PROD] X# console [eu)dojiminny v037 A1 A35 V64 ^S team1dSUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domairu 1<->1.n: ON U.team id = t.idars c ON c.user id = u.id AND c.status = 'active' AND c.calendar provider idLIKE 1%o)team_domains tdteam_id = t.ioLdeleted at TS NUlI.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id,'@', -1)).id, t.name, calendar_domain.name, calendar_domain;rom users u join calendars c 1<->1..n: on c.user_id = u.idamid - 909.rom activities where id = 74049485: # team 563 crm 537rom activities where id = 73272382: # team 563 crm 537rom activities where id = 64400389: # team 563 crm 537'om activities where id = 58081273: # team 563 crm 537om activities where id = 54520297: # team 563 crm 537om participants where activity id = 58081273:om activities where crm_configuration_id = 537 and provider = 'aircall't 1d = 19003658 order by uodated at desc:com contacts where crm confiquration id = 537 and id = 35957759:om accounts where com confiauration id = 537 and id = 19003658:select * from automated_report_results where id = 1976;select * from automated_reports where id = 583;select * from activity_searches where id = 87714;select *from activity search filtens where activity search id = 87714÷SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = vuidor uvid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;SELECT * FROM crm confiqurations WHERE provider = 'hubspot':select * from rate limitsCascade• Hubspot Rate LimitDO l understand it correctly:Thinkinganother 990 in 90I'm working through a rate limitina scenario where 1000 jobs are dispatched immediately, each making a search request to HubSpot, and I need toconsider how the ProviderRateLimiter with a quota of 4 requests per second would handle this against HubSpot's actual limits of 4-5 requests per110Ask anvthina (&:+-D<> Code Claude Qnus 17 MediumW Windsurf Teams66.52Po 4 space....
|
1595
|
NULL
|
NULL
|
NULL
|
|
1597
|
63
|
23
|
2026-05-07T09:00:49.875582+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778144449875_m1.jpg...
|
Slack
|
Toast (DM) - Jiminny Inc - 3 new items - Slack
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
All, 4 unread
DMs
Add new tab
Reminder
DM
Reschedule
Mark as read
Clear
More actions
Stoyan Tanev:
Здрасти, за този тикет:
[URL_WITH_CREDENTIALS] Ivanov
@Nikolay Ivanov
transitioned a Bug you are watching from
Code Review
⟶
Deployed
…
Wednesday, April 29th
Aneliya Angelova
Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev
Apr 29th
да
Stoyan Tanev
DM
Apr 29th
трябва ли да синкваме нещо от наша страна?
Tuesday, April 28th
Stefka Stoyanova
Thread
Apr 28th
тия тикети е добре да влезнат в другия спринт ли? сложете някакви естимейти тогава
Ves
Thread in
DM
:
исках да те питам credentials на AWS. Направих server на постмарк за QAI но не знам как да добавя key, май вече не е през env. Има ли някакви инструкции?
Apr 28th
смени го в Circle CI env на новия токен който си направил
Home
Messages
Messages
About
Jump to date
Toast
APP
May 5th at 10:00:03 AM
10:00 AM
Review
prophet
#493 JY-20566: Re-eval action items
#493 JY-20566: Re-eval action items
17 hours old・22 files changed・
@Steliyan Georgiev
@Steliyan Georgiev
Added by
Toast for GitHub
Toast for GitHub
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
6 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
Jump to date
Toast
APP
Yesterday at 10:00:03 AM
10:00 AM
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
7 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
New
Toast
APP
Today at 10:00:02 AM
10:00 AM
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
8 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Channel...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"All, 4 unread","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"DMs","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Add new tab","depth":20,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reminder","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DM","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Reschedule","depth":23,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mark as read","depth":23,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Clear","depth":23,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":23,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Stoyan Tanev:","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Здрасти, за този тикет:","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"https://jiminny.atlassian.net/browse/SRD-6793","depth":23,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"https://jiminny.atlassian.net/browse/SRD-6793","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Mark complete","depth":23,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reminder","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Post in","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Incomplete","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Just now","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov:","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"For those using","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"make cs-fix","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"and getting annoyed by how long it takes (since it scans the entire project), you can now use","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"make cs-fix-branch","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":". It will fix only the files that differ from","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"master","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":", and it runs in just a couple of seconds","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Mark complete","depth":23,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"App","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Mark as unread","depth":23,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Clear","depth":23,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":23,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"[no preview available]","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Monday, May 4th","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"App","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Monday","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"@Nikolay Ivanov","depth":23,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"@Nikolay Ivanov","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"transitioned a Bug you are watching from","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Code Review","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"⟶","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Deployed","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"…","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Wednesday, April 29th","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apr 29th","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DM","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apr 29th","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"трябва ли да синкваме нещо от наша страна?","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Tuesday, April 28th","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Thread","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apr 28th","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"тия тикети е добре да влезнат в другия спринт ли? сложете някакви естимейти тогава","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Thread in","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DM","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":":","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"исках да те питам credentials на AWS. Направих server на постмарк за QAI но не знам как да добавя key, май вече не е през env. Има ли някакви инструкции?","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Apr 28th","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"смени го в Circle CI env на новия токен който си направил","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Home","depth":17,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Messages","depth":17,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"About","depth":17,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Jump to date","depth":24,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Toast","depth":25,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"APP","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"May 5th at 10:00:03 AM","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:00 AM","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Review","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"prophet","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"#493 JY-20566: Re-eval action items","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#493 JY-20566: Re-eval action items","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"17 hours old・22 files changed・","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"@Steliyan Georgiev","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"@Steliyan Georgiev","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Resolve Conflicts","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"#11443 Test hublets latency","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 Test hublets latency","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"4 months old・20 files changed","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"#11327 JY-19501 webhook based opportunity sync","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 JY-19501 webhook based opportunity sync","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Show more","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Needs Love","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":28,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"6 days old・1 file changed","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":24,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Toast","depth":25,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"APP","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Yesterday at 10:00:03 AM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:00 AM","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Resolve Conflicts","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#11443 Test hublets latency","depth":28,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 Test hublets latency","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4 months old・20 files changed","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#11327 JY-19501 webhook based opportunity sync","depth":28,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 JY-19501 webhook based opportunity sync","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Show more","depth":27,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Needs Love","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":28,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"7 days old・1 file changed","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":27,"on_screen":false,"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":27,"on_screen":false,"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":27,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":27,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":27,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Jump to date","depth":24,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Toast","depth":25,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"APP","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 10:00:02 AM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:00 AM","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Resolve Conflicts","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#11443 Test hublets latency","depth":28,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11443 Test hublets latency","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4 months old・20 files changed","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#11327 JY-19501 webhook based opportunity sync","depth":28,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11327 JY-19501 webhook based opportunity sync","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Show more","depth":27,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Needs Love","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":28,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#12024 JY-20773 fix user pilot tracking ofr automated report generated","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"8 days old・1 file changed","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Added by","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Toast for GitHub","depth":27,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Toast for GitHub","depth":28,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":27,"on_screen":false,"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":27,"on_screen":false,"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":27,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":27,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":27,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":24,"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Channel","depth":11,"on_screen":true,"role_description":"text"}]...
|
-9097146115657707968
|
-3589467510854988474
|
click
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
All, 4 unread
DMs
Add new tab
Reminder
DM
Reschedule
Mark as read
Clear
More actions
Stoyan Tanev:
Здрасти, за този тикет:
[URL_WITH_CREDENTIALS] Ivanov
@Nikolay Ivanov
transitioned a Bug you are watching from
Code Review
⟶
Deployed
…
Wednesday, April 29th
Aneliya Angelova
Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev
Apr 29th
да
Stoyan Tanev
DM
Apr 29th
трябва ли да синкваме нещо от наша страна?
Tuesday, April 28th
Stefka Stoyanova
Thread
Apr 28th
тия тикети е добре да влезнат в другия спринт ли? сложете някакви естимейти тогава
Ves
Thread in
DM
:
исках да те питам credentials на AWS. Направих server на постмарк за QAI но не знам как да добавя key, май вече не е през env. Има ли някакви инструкции?
Apr 28th
смени го в Circle CI env на новия токен който си направил
Home
Messages
Messages
About
Jump to date
Toast
APP
May 5th at 10:00:03 AM
10:00 AM
Review
prophet
#493 JY-20566: Re-eval action items
#493 JY-20566: Re-eval action items
17 hours old・22 files changed・
@Steliyan Georgiev
@Steliyan Georgiev
Added by
Toast for GitHub
Toast for GitHub
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
6 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
Jump to date
Toast
APP
Yesterday at 10:00:03 AM
10:00 AM
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
7 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
New
Toast
APP
Today at 10:00:02 AM
10:00 AM
Resolve Conflicts
app
#11443 Test hublets latency
#11443 Test hublets latency
4 months old・20 files changed
#11327 JY-19501 webhook based opportunity sync
#11327 JY-19501 webhook based opportunity sync
Show more
Added by
Toast for GitHub
Toast for GitHub
Needs Love
app
#12024 JY-20773 fix user pilot tracking ofr automated report generated
#12024 JY-20773 fix user pilot tracking ofr automated report generated
8 days old・1 file changed
Added by
Toast for GitHub
Toast for GitHub
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Channel
PhpStormFileEditViewNavigateCodeLaravelRefactorRunToolsGitWindowHelplahlSupport Daily • in 3hPROD (ssh)DOCKER081DEV (-zsh)₴2APP (-zsh)83-zshX t1DOCKER (-zsh)Last login: Thu May 7 09:29:14 on consoleX 12PROD (ssh)Run 'do-release-upgrade' to upgrade to it.Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/infrastructure/dev/docker or its parentsD.Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/infrastructure/dev/docker or its parentsukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/infrastructure/dev/docker (develop) $• ₴4100% <78Thu 7 May 12:00:49181screenpipe"• *5PROD*** System restart required ***Last login: Mon Apr 27 07:45:27 2026 from 212.5.153.87lukas@jiminny-prod-bastion:~$ 0X L3 EU (-zsh)Last login: Thu May 7 09:29:14 on consolePoetry could not find a pyproject.toml file in /Users/lukas or its parentsPoetry could not find a pyproject.toml file in /Users/lukas or its parents@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ I|X T4 STAGE (-zsh)Last login: Thu May 7 09:29:14 on consolePoetry could not find a pyproject.toml file in /Users/lukas or its parentsPoetry could not find a pyproject.toml file in /Users/lukas or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny$X T5QA (-zsh)Last login: Thu May 7 09:44:56on ttys002Poetry could not find a pyproject.toml file in /Users/lukas or its parentsPoetry could not find a pyproject.tomlfile in /Users/lukas or its parentsX T6 FE (-zsh)Last login: Thu May 7 09:44:56 on ttys004Poetry could not find a pyproject.toml file in /Users/lukas or its parentsPoetry could not find a pyproject.tomlfile in /Users/lukas or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ DX W7 ExT(-zsh)Poetry could not find a pyproject.toml file in /Users/lukas or its parentsPoetry could not find a pyproject.tomlfile in /Users/lukas or its parentslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~ $ I|STAGEFRONTENDEXTENSION...
|
1594
|
NULL
|
NULL
|
NULL
|
|
18692
|
805
|
12
|
2026-05-11T11:40:20.442515+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778499620442_m2.jpg...
|
PhpStorm
|
faVsco.js – MatchActivityCrmData.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormViewINavicareCodeLaravelKeractorTOOISWindo PhpStormViewINavicareCodeLaravelKeractorTOOISWindowFV faVsco.js°9 JY-20725-handle-HS-search-rate-limitProiect v© UserAutomatedReportsController.php© OutOfBoundsException.plQuotaExceededExceptior(c) HubSoot/Service.onp© SyncCrmEntitiesTrait.php© CachedCrmServiceDecorator.phpA console [STAGING]-kateLimitexception.ong© RegistrationInvitationMisr© RequestQueuedForDeferrResponseException.phpc Job.phoRateLimitException.php© RingCentralException.php(C)PaqinationState.phpC) MatchCrmData.phpC) CrmObiectsResolver.phoRingCentralExtensionNotl•+ maxExcentionsX P CcW÷I Y.RuntimeException.php© CheскAnaketrykemotematch.pnpMatchactivitycrmData.phpx© ProviderRateLimiter.php(C) PaqinationContia.php1/141715namespace Jiminny Jods.Crm1/161717) SequenceNumberExcepti© ServicelntegrationExcept( ServiceUnavailable ExcepSidekickSettingsExceptio() Socia Account NotFounde© SocialAccountTokeninvaliSvncActivitvExcention.ohTenantisolationException© TextRelayException.php© TooManyFailedActivities.© TranscriptionNotindexed!© UnexpectedCallExceptior© UnexpectedEloquentMod© UnexpectedValueExcepti© ZipAttackException.php› D FFMpeg> D FormatsD Guards1V8 AVuse Exceptionuse Illuminate\Contracts\Queue\ShouldBeUnique;use Illuminate \Contracts \Queue \ShouldQueue;use Illuminate \Database Connection;use Illuminate \Queue\InteractsWithQueue;use Illuminate \Queue\SerializesModelsuse Illuminate\Support\Facades \Log;use Jiminny Component \Queue \Constantsuse Jiminny Exceptions \InvalidArgumentException;use Jiminny\Exceptions\RateLimitExceptionuse laiminny .iohs winh.use Jiminny\Jobs\MiddLeware\HandleHubspotRateLimit;use Jiminny Models \Activity:use Jiminny Models\Crm\Configuration:use Jiminny Repositories ActivityRepository:use Jiminny\Services\Crm\CrmActivityService:use Psr\Container\ContainerExceptionInterface:1/18171911728|- 17211-172217231727-=172— 17291-173017321733-17541735Console,Log xChanges 12 filesE.env.local app© Client.php app/Services/Crm/Hubspot© HandleHubspotRateLimit.php app/Jobs/Middleware© HandleHubspotRateLimitTest.php tests/Unit/Jobs/Middleware@ HubspotClientInterface.php app/Services/Crm/Hubspot© HubspotPaginationService.php app/Services/Crm/Hubspot/Pagination© JiminnyDebugCommand.php app/Console/CommandsTJ0 + → Side-by-side viewer •8 35f036ac app/Exceptions/RateLimitException.phpDo not ignoreHighlight wordsx 13 B?declare(strict types=1)namespace Jiminny Exceptionsclass RateLimitException extends LoqicExcentionphp loaaina.php confia© MatchActivityCrmData.php app/Jobs/Crm© PaginationState.php app/Services/Crm/Hubspot/Pagination© RateLimitException.pho app/ExceptionsC RateLimitExceptionTest.pho tests/Unit/ExceptionsUnversioned Files 9 files=env.nikilocal appenv.other aoo@ CanAccessAiReportsTest.phn tests/Unit/Policies(C) CreateMockAsk.liminnvReoortResultCommand.ohn aoo/Console/Commands/Rre tavicon ico nublic= ids tyt ann"2 raw sal auerv sal anniC)SimulateWehhookcCommand nhn ann/Console/Commands/Crm/HubsnotML WERHOOK FIL TEPING IMDI EMENTATION md andTacts naccod. 12 (todav 12:02A SF (jiminny@localhost]4 HS_local jiminny@localhost]# console [PKol)# console [eu)• Preparation tor kerl.. In 20 m100% L2• Mon 11 May 14:40:20HandleHubspotRateLimitTest v+0..[2026-05-11 11:20:43] local.ERROR: Failed to refresh HubSpot token {"account_id":1372, "updated_at": "2025 mm[2026-05-11 11:20:43] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlatian[2026-05-11 11:20:48] local.INF0: Jiminny\Console\Commands\Command::run Memory usage before starting command[2026-05-11 11:20:48] local.INF0: Jiminny\Console\Commands\Command::run Memory usage before starting command {"12020-05-11 11.20.48 LocaL.LNFU. LHUDspor Journal commana scaruing polling service1"correlac1on.10: 754015[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Pollingl Service starting {"memory_limit":"256M", "max_execut2020-05-11 11:20:48 Local. LNFU:Hubspor Journal Polling Acqulrea polling lock ""explres ac": 2020-05-1111132026-05-11 11.20.48 LocaL.LNFU:2026-05-11 11.20.48 LocaL.LNFU:Jaminny console commanos.comnremory usage tor commano ""2826-05-11 11:20:49 Local.INF0:Jiminny\Console\Commands\Command::run Memory usage for co2826-05-11 11:20:49 Local.INF0:HubSoot Journal Auth Successfully obtained new access token «"expires_1n":2826-05-11 11:20:49 Local.INF0:2826-05-11 11:20:53 Local.INF0:Memory usage before starting command "[2026-05-11 11:20:53] Local.INF0: Jiminny\Console\Commands\Command: :run Memory usage for command {"command" : "o2026-05-11 11-20:5411LocaL.INFO"HuoSoot Journal Pollinal No data2026-05-11 11:20:5611local.INFO: Jiminny \Console\Commands \Command::run Memory usage before starting command f2026-05-11 11:20:571 Local.TNE0: Jiminnv Console Commands \Command::run Memory usage for command t"command":"cr[2026-05-11 11:20:591 local. INF0:[HubSpot Journal Pollingl No data"correlation 1d":"054d156d-8a4f-4592-a0ce2026-05-11 11:21:151 LocolINF0: HubSoot Journal Polzinal No data"correlation 1d"."054d156d-8a4f-4592-a046[2026-05-11 11:21:22] Local. INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"[2026-05-11 11:21:22] local.INF0: [ScheduleBotCommand] Number of activities to be captured: 0 1"correlation_ic[2026-05-11 11:21:22] local.INF0: Jiminny Console\Commands\Command::run Memory usage for command {"command" : "me(2026-05-11 11•21•311 1ocal TAE0• Liminnv Console Commands Command• •nun Memony ucade hefonp stantina command !2026-05-11 11•21•311 local TAS0• liminnv Console Commands Command• •nun Memony ucade fon command &"command"."dHubspot Rate Limit ReOk Where is it used, will I break something it is replace LogicException with RuntimeException in RateLimitException?Searched RateLimitException in ~/iminnylapp (php) (44))Thought for 2s ›Searched throw new RateLimit Excention and pertormed 1 other auervY2, 11n0 AM Giiy usage quota is exhausted. Purchase extra usage to continue using premium models. Quota resets Maywal .Your included daily usage quota is exhausted. Purchase extra usage to continue using premium models. Quota resets May 12, 11:00Ask anything (&AL)<> CodeClaude Opus 4.7 Medium2 differencesnamespace Jiminny Exceptionsuse Throwableclass RateLimitExcention extends RuntimeExcentionpublic function __constructStrina Smessage =private readonly int $retryAfter = 1,Throwahil e Sarevious = nuipublic function getRetryAfterO: intnotunn may/Cthic-snotnvAfton 1)•W Windsurf Teams 27:7 UTF-8 P 4 spaces...
|
NULL
|
-9096538731895467524
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormViewINavicareCodeLaravelKeractorTOOISWindo PhpStormViewINavicareCodeLaravelKeractorTOOISWindowFV faVsco.js°9 JY-20725-handle-HS-search-rate-limitProiect v© UserAutomatedReportsController.php© OutOfBoundsException.plQuotaExceededExceptior(c) HubSoot/Service.onp© SyncCrmEntitiesTrait.php© CachedCrmServiceDecorator.phpA console [STAGING]-kateLimitexception.ong© RegistrationInvitationMisr© RequestQueuedForDeferrResponseException.phpc Job.phoRateLimitException.php© RingCentralException.php(C)PaqinationState.phpC) MatchCrmData.phpC) CrmObiectsResolver.phoRingCentralExtensionNotl•+ maxExcentionsX P CcW÷I Y.RuntimeException.php© CheскAnaketrykemotematch.pnpMatchactivitycrmData.phpx© ProviderRateLimiter.php(C) PaqinationContia.php1/141715namespace Jiminny Jods.Crm1/161717) SequenceNumberExcepti© ServicelntegrationExcept( ServiceUnavailable ExcepSidekickSettingsExceptio() Socia Account NotFounde© SocialAccountTokeninvaliSvncActivitvExcention.ohTenantisolationException© TextRelayException.php© TooManyFailedActivities.© TranscriptionNotindexed!© UnexpectedCallExceptior© UnexpectedEloquentMod© UnexpectedValueExcepti© ZipAttackException.php› D FFMpeg> D FormatsD Guards1V8 AVuse Exceptionuse Illuminate\Contracts\Queue\ShouldBeUnique;use Illuminate \Contracts \Queue \ShouldQueue;use Illuminate \Database Connection;use Illuminate \Queue\InteractsWithQueue;use Illuminate \Queue\SerializesModelsuse Illuminate\Support\Facades \Log;use Jiminny Component \Queue \Constantsuse Jiminny Exceptions \InvalidArgumentException;use Jiminny\Exceptions\RateLimitExceptionuse laiminny .iohs winh.use Jiminny\Jobs\MiddLeware\HandleHubspotRateLimit;use Jiminny Models \Activity:use Jiminny Models\Crm\Configuration:use Jiminny Repositories ActivityRepository:use Jiminny\Services\Crm\CrmActivityService:use Psr\Container\ContainerExceptionInterface:1/18171911728|- 17211-172217231727-=172— 17291-173017321733-17541735Console,Log xChanges 12 filesE.env.local app© Client.php app/Services/Crm/Hubspot© HandleHubspotRateLimit.php app/Jobs/Middleware© HandleHubspotRateLimitTest.php tests/Unit/Jobs/Middleware@ HubspotClientInterface.php app/Services/Crm/Hubspot© HubspotPaginationService.php app/Services/Crm/Hubspot/Pagination© JiminnyDebugCommand.php app/Console/CommandsTJ0 + → Side-by-side viewer •8 35f036ac app/Exceptions/RateLimitException.phpDo not ignoreHighlight wordsx 13 B?declare(strict types=1)namespace Jiminny Exceptionsclass RateLimitException extends LoqicExcentionphp loaaina.php confia© MatchActivityCrmData.php app/Jobs/Crm© PaginationState.php app/Services/Crm/Hubspot/Pagination© RateLimitException.pho app/ExceptionsC RateLimitExceptionTest.pho tests/Unit/ExceptionsUnversioned Files 9 files=env.nikilocal appenv.other aoo@ CanAccessAiReportsTest.phn tests/Unit/Policies(C) CreateMockAsk.liminnvReoortResultCommand.ohn aoo/Console/Commands/Rre tavicon ico nublic= ids tyt ann"2 raw sal auerv sal anniC)SimulateWehhookcCommand nhn ann/Console/Commands/Crm/HubsnotML WERHOOK FIL TEPING IMDI EMENTATION md andTacts naccod. 12 (todav 12:02A SF (jiminny@localhost]4 HS_local jiminny@localhost]# console [PKol)# console [eu)• Preparation tor kerl.. In 20 m100% L2• Mon 11 May 14:40:20HandleHubspotRateLimitTest v+0..[2026-05-11 11:20:43] local.ERROR: Failed to refresh HubSpot token {"account_id":1372, "updated_at": "2025 mm[2026-05-11 11:20:43] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlatian[2026-05-11 11:20:48] local.INF0: Jiminny\Console\Commands\Command::run Memory usage before starting command[2026-05-11 11:20:48] local.INF0: Jiminny\Console\Commands\Command::run Memory usage before starting command {"12020-05-11 11.20.48 LocaL.LNFU. LHUDspor Journal commana scaruing polling service1"correlac1on.10: 754015[2026-05-11 11:20:48] local.INFO: [HubSpot Journal Pollingl Service starting {"memory_limit":"256M", "max_execut2020-05-11 11:20:48 Local. LNFU:Hubspor Journal Polling Acqulrea polling lock ""explres ac": 2020-05-1111132026-05-11 11.20.48 LocaL.LNFU:2026-05-11 11.20.48 LocaL.LNFU:Jaminny console commanos.comnremory usage tor commano ""2826-05-11 11:20:49 Local.INF0:Jiminny\Console\Commands\Command::run Memory usage for co2826-05-11 11:20:49 Local.INF0:HubSoot Journal Auth Successfully obtained new access token «"expires_1n":2826-05-11 11:20:49 Local.INF0:2826-05-11 11:20:53 Local.INF0:Memory usage before starting command "[2026-05-11 11:20:53] Local.INF0: Jiminny\Console\Commands\Command: :run Memory usage for command {"command" : "o2026-05-11 11-20:5411LocaL.INFO"HuoSoot Journal Pollinal No data2026-05-11 11:20:5611local.INFO: Jiminny \Console\Commands \Command::run Memory usage before starting command f2026-05-11 11:20:571 Local.TNE0: Jiminnv Console Commands \Command::run Memory usage for command t"command":"cr[2026-05-11 11:20:591 local. INF0:[HubSpot Journal Pollingl No data"correlation 1d":"054d156d-8a4f-4592-a0ce2026-05-11 11:21:151 LocolINF0: HubSoot Journal Polzinal No data"correlation 1d"."054d156d-8a4f-4592-a046[2026-05-11 11:21:22] Local. INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"[2026-05-11 11:21:22] local.INF0: [ScheduleBotCommand] Number of activities to be captured: 0 1"correlation_ic[2026-05-11 11:21:22] local.INF0: Jiminny Console\Commands\Command::run Memory usage for command {"command" : "me(2026-05-11 11•21•311 1ocal TAE0• Liminnv Console Commands Command• •nun Memony ucade hefonp stantina command !2026-05-11 11•21•311 local TAS0• liminnv Console Commands Command• •nun Memony ucade fon command &"command"."dHubspot Rate Limit ReOk Where is it used, will I break something it is replace LogicException with RuntimeException in RateLimitException?Searched RateLimitException in ~/iminnylapp (php) (44))Thought for 2s ›Searched throw new RateLimit Excention and pertormed 1 other auervY2, 11n0 AM Giiy usage quota is exhausted. Purchase extra usage to continue using premium models. Quota resets Maywal .Your included daily usage quota is exhausted. Purchase extra usage to continue using premium models. Quota resets May 12, 11:00Ask anything (&AL)<> CodeClaude Opus 4.7 Medium2 differencesnamespace Jiminny Exceptionsuse Throwableclass RateLimitExcention extends RuntimeExcentionpublic function __constructStrina Smessage =private readonly int $retryAfter = 1,Throwahil e Sarevious = nuipublic function getRetryAfterO: intnotunn may/Cthic-snotnvAfton 1)•W Windsurf Teams 27:7 UTF-8 P 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
22108
|
965
|
12
|
2026-05-12T06:49:27.559134+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778568567559_m2.jpg...
|
Firefox
|
Platform Sprint 3 Q2 - Platform Team - Scrum Board Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira — Work...
|
True
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
New Tab
New Tab
Jy 20820 es reindex stream model h New Tab
New Tab
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Pull requests · jiminny/app
Pull requests · jiminny/app
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.29986703,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"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.3131649,"top":0.06304868,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":4,"bounds":{"left":0.29986703,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":5,"bounds":{"left":0.3131649,"top":0.09577015,"width":0.16888298,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":4,"bounds":{"left":0.29986703,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":5,"bounds":{"left":0.3131649,"top":0.12849163,"width":0.16140293,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.29986703,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.3131649,"top":0.16121309,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.29986703,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.3131649,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.29986703,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.3131649,"top":0.22665602,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":4,"bounds":{"left":0.29986703,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":5,"bounds":{"left":0.3131649,"top":0.25937748,"width":0.1200133,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":4,"bounds":{"left":0.29986703,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":5,"bounds":{"left":0.3131649,"top":0.29209897,"width":0.19331782,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20776] Automated report - sentry - Jira","depth":4,"bounds":{"left":0.29986703,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20776] Automated report - sentry - Jira","depth":5,"bounds":{"left":0.3131649,"top":0.32482043,"width":0.07646277,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":4,"bounds":{"left":0.29986703,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":5,"bounds":{"left":0.3131649,"top":0.3575419,"width":0.40475398,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":4,"bounds":{"left":0.29986703,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":5,"bounds":{"left":0.3131649,"top":0.39026338,"width":0.40475398,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.29986703,"top":0.41181165,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.3131649,"top":0.42298484,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.3671875,"top":0.41899443,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.30269283,"top":0.4461293,"width":0.07413564,"height":0.025538707},"on_screen":true,"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.30269283,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.31366357,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-9093742680405457588
|
-3011410393329092466
|
click
|
accessibility
|
NULL
|
New Tab
New Tab
Jy 20820 es reindex stream model h New Tab
New Tab
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Pull requests · jiminny/app
Pull requests · jiminny/app
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
25084
|
1052
|
26
|
2026-05-12T10:42:32.049545+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778582552049_m1.jpg...
|
Firefox
|
JY-20773 fix user pilot tracking ofr automated rep JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app — Work...
|
True
|
github.com/jiminny/app/pull/12024
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Unnamed Group
TypeError: League\Flysystem\Filesyst Unnamed Group
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
CloudWatch | us-east-2
CloudWatch | us-east-2
Unnamed Group
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Pull requests · jiminny/app
Pull requests · jiminny/app
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app
JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app
Data Explorer
Data Explorer
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
Jiminny
Jiminny
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
Platform Team - Backlog - Jira
Platform Team - Backlog - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (4)
Security and quality
(
4
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
JY-20773 fix user pilot tracking for automated report generated #12024 Edit title
JY-20773 fix user pilot tracking for automated report generated
#
12024
Edit title
Awaiting approval
Awaiting approval
Code
Code
Open
LakyLak
LakyLak
wants to merge 2 commits into
master
master
from
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20773-fix-automated-reports-user-pilot-tracking
Copy head branch name to clipboard
Lines changed: 3 additions & 0 deletions
Conversation (1)
Conversation
(
1
)
Commits (2)
Commits
(
2
)
Checks (3)
Checks
(
3
)
Files changed (1)
Files changed
(
1
)
Conversation...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Unnamed Group","depth":4,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXRadioButton","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"on_screen":true,"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,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Unnamed Group","depth":4,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXRadioButton","text":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20776] Automated report - sentry - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20776] Automated report - sentry - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Data Explorer","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Data Explorer","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20776] Automated report - sentry - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20776] Automated report - sentry - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Platform Team - Backlog - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Team - Backlog - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (32)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"32","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (4)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"JY-20773 fix user pilot tracking for automated report generated #12024 Edit title","depth":13,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20773 fix user pilot tracking for automated report generated","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12024","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Awaiting approval","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Awaiting approval","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Code","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Code","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 2 commits into","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":15,"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20773-fix-automated-reports-user-pilot-tracking","depth":16,"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20773-fix-automated-reports-user-pilot-tracking","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines changed: 3 additions & 0 deletions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation (1)","depth":16,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (2)","depth":16,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks (3)","depth":16,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed (1)","depth":16,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Files changed","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Conversation","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"}]...
|
-9092849697388020852
|
-426343107148416896
|
click
|
accessibility
|
NULL
|
Unnamed Group
TypeError: League\Flysystem\Filesyst Unnamed Group
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
CloudWatch | us-east-2
CloudWatch | us-east-2
Unnamed Group
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Pull requests · jiminny/app
Pull requests · jiminny/app
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app
JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app
Data Explorer
Data Explorer
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
Jiminny
Jiminny
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
Platform Team - Backlog - Jira
Platform Team - Backlog - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (4)
Security and quality
(
4
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
JY-20773 fix user pilot tracking for automated report generated #12024 Edit title
JY-20773 fix user pilot tracking for automated report generated
#
12024
Edit title
Awaiting approval
Awaiting approval
Code
Code
Open
LakyLak
LakyLak
wants to merge 2 commits into
master
master
from
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20773-fix-automated-reports-user-pilot-tracking
Copy head branch name to clipboard
Lines changed: 3 additions & 0 deletions
Conversation (1)
Conversation
(
1
)
Commits (2)
Commits
(
2
)
Checks (3)
Checks
(
3
)
Files changed (1)
Files changed
(
1
)
Conversation...
|
25082
|
NULL
|
NULL
|
NULL
|
|
3192
|
123
|
10
|
2026-05-07T12:06:01.015973+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778155561015_m1.jpg...
|
iTerm2
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
PostmanFileEditViewWindowHelp$0lohlSupport Daily • PostmanFileEditViewWindowHelp$0lohlSupport Daily • now100% <8DEV (docker)DOCKERO ₴1DEV (docker)H82APP (-zsh)-zsh• $4screenpipe"•$55.95ms DONE-zshThu 7 May 15:06:00T81₴6viewsjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-nudges:worker-nudges_00:stoppedjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedJiminny-worker-processing-3:7iminny-worker-processing-3_00: stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00:stoppedjiminny-worker-processing-5: jiminny-worker-processing-5_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-download:worker-download_00: stoppedworker:worker_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedworker-audio:worker-audio_00: stoppedworker-emails:worker-emails_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:1iminny-worker-processing-2 00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugSyncing opportunity 0Syncing opportunity 25Syncing opportunity 50Syncing opportunity 75Syncing opportunity 100root@docker_lamp_1:/home/jiminny# ]DEV...
|
NULL
|
-9092464748005920751
|
NULL
|
click
|
ocr
|
NULL
|
PostmanFileEditViewWindowHelp$0lohlSupport Daily • PostmanFileEditViewWindowHelp$0lohlSupport Daily • now100% <8DEV (docker)DOCKERO ₴1DEV (docker)H82APP (-zsh)-zsh• $4screenpipe"•$55.95ms DONE-zshThu 7 May 15:06:00T81₴6viewsjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-nudges:worker-nudges_00:stoppedjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedJiminny-worker-processing-3:7iminny-worker-processing-3_00: stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00:stoppedjiminny-worker-processing-5: jiminny-worker-processing-5_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-download:worker-download_00: stoppedworker:worker_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedworker-audio:worker-audio_00: stoppedworker-emails:worker-emails_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:1iminny-worker-processing-2 00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugSyncing opportunity 0Syncing opportunity 25Syncing opportunity 50Syncing opportunity 75Syncing opportunity 100root@docker_lamp_1:/home/jiminny# ]DEV...
|
3190
|
NULL
|
NULL
|
NULL
|
|
17045
|
762
|
17
|
2026-05-11T09:59:44.371650+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493584371_m1.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17046
|
763
|
20
|
2026-05-11T09:59:44.338323+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493584338_m2.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09541223,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","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.82413566,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"bounds":{"left":0.8394282,"top":0.019952115,"width":0.076130316,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"bounds":{"left":0.122340426,"top":0.24581006,"width":0.30585107,"height":0.75418997},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"bounds":{"left":0.6296542,"top":0.10055866,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6409575,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.64827126,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"bounds":{"left":0.43018618,"top":0.09736632,"width":0.56981385,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
17039
|
NULL
|
NULL
|
NULL
|
|
17049
|
763
|
22
|
2026-05-11T09:59:54.202862+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493594202_m2.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09541223,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","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.82413566,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"bounds":{"left":0.8394282,"top":0.019952115,"width":0.076130316,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"bounds":{"left":0.122340426,"top":0.24581006,"width":0.30585107,"height":0.75418997},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"bounds":{"left":0.6296542,"top":0.10055866,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6409575,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.64827126,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"bounds":{"left":0.43018618,"top":0.09736632,"width":0.56981385,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.05086436,"top":0.05027933,"width":0.008643617,"height":0.01915403},"on_screen":true,"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.061835106,"top":0.05027933,"width":0.008643617,"height":0.01915403},"on_screen":true,"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.07047872,"top":0.05027933,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.07912234,"top":0.05027933,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.087765954,"top":0.05027933,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17050
|
762
|
19
|
2026-05-11T09:59:56.639170+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493596639_m1.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17067
|
764
|
4
|
2026-05-11T10:02:30.291987+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493750291_m1.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
17065
|
NULL
|
NULL
|
NULL
|
|
17068
|
765
|
4
|
2026-05-11T10:02:30.291948+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493750291_m2.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09541223,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","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.82413566,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"bounds":{"left":0.8394282,"top":0.019952115,"width":0.076130316,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"bounds":{"left":0.122340426,"top":0.24581006,"width":0.30585107,"height":0.75418997},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"bounds":{"left":0.6296542,"top":0.10055866,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6409575,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.64827126,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"bounds":{"left":0.43018618,"top":0.09736632,"width":0.56981385,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
17066
|
NULL
|
NULL
|
NULL
|
|
17078
|
764
|
10
|
2026-05-11T10:02:47.531981+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493767531_m1.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
17076
|
NULL
|
NULL
|
NULL
|
|
17079
|
765
|
9
|
2026-05-11T10:02:47.531965+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493767531_m2.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09541223,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","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.82413566,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"bounds":{"left":0.8394282,"top":0.019952115,"width":0.076130316,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"bounds":{"left":0.122340426,"top":0.24581006,"width":0.30585107,"height":0.75418997},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"bounds":{"left":0.6296542,"top":0.10055866,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6409575,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.64827126,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"bounds":{"left":0.43018618,"top":0.09736632,"width":0.56981385,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
17082
|
765
|
11
|
2026-05-11T10:02:49.676163+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778493769676_m2.jpg...
|
PhpStorm
|
faVsco.js – HandleHubspotRateLimitTest.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20725-handle-HS-search-rate-limit, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.09541223,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20725-handle-HS-search-rate-limit","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.82413566,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HandleHubspotRateLimitTest","depth":6,"bounds":{"left":0.8394282,"top":0.019952115,"width":0.076130316,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'HandleHubspotRateLimitTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\n }\n}","depth":4,"bounds":{"left":0.122340426,"top":0.24581006,"width":0.30585107,"height":0.75418997},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\Middleware;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\n\n#[CoversClass(HandleHubspotRateLimit::class)]\nclass HandleHubspotRateLimitTest extends TestCase\n{\n private const int MAX_RETRY_DELAY = 600;\n private const int MIN_RETRY_DELAY = 1;\n private const int JITTER_SECONDS = 5;\n\n private HandleHubspotRateLimit $middleware;\n\n protected function setUp(): void\n {\n parent::setUp();\n\n $this->middleware = new HandleHubspotRateLimit();\n }\n\n public function testPassesThroughWhenNoExceptionThrown(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $called = false;\n $next = function (object $passed) use ($job, &$called): void {\n $this->assertSame($job, $passed);\n $called = true;\n };\n\n $this->middleware->handle($job, $next);\n\n $this->assertTrue($called);\n }\n\n public function testPropagatesNonRateLimitExceptions(): void\n {\n $job = $this->createMock(Job::class);\n $job->expects($this->never())->method('release');\n\n $next = static function (): void {\n throw new Exception('Database is down');\n };\n\n $this->expectException(Exception::class);\n $this->expectExceptionMessage('Database is down');\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>\n */\n public static function delayClampingProvider(): array\n {\n return [\n 'short retry uses retry_after as floor' => [\n 'retryAfter' => 1,\n 'expectedMin' => self::MIN_RETRY_DELAY,\n 'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n 'medium retry passes through' => [\n 'retryAfter' => 30,\n 'expectedMin' => 30,\n 'expectedMax' => 30 + self::JITTER_SECONDS,\n ],\n 'large retry clamped to max' => [\n 'retryAfter' => 86400,\n 'expectedMin' => self::MAX_RETRY_DELAY,\n 'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,\n ],\n ];\n }\n\n #[DataProvider('delayClampingProvider')]\n public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void\n {\n Log::shouldReceive('info')->zeroOrMoreTimes();\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn(1);\n $job->expects($this->once())\n ->method('release')\n ->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {\n return $delay >= $expectedMin && $delay <= $expectedMax;\n }));\n\n $next = static function () use ($retryAfter): void {\n throw new RateLimitException('rate limited', $retryAfter);\n };\n\n $this->middleware->handle($job, $next);\n }\n\n /**\n * @return array<string, array{attempts: int, shouldLog: bool}>\n */\n public static function logSamplingProvider(): array\n {\n return [\n 'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],\n 'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],\n 'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],\n 'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],\n 'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],\n 'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],\n 'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],\n 'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],\n ];\n }\n\n #[DataProvider('logSamplingProvider')]\n public function testLogSampling(int $attempts, bool $shouldLog): void\n {\n if ($shouldLog) {\n Log::shouldReceive('info')\n ->once()\n ->with(\n '[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',\n $this->callback(static function (array $context) use ($attempts): bool {\n return $context['attempts'] === $attempts\n && $context['retry_after'] === 1\n && isset($context['delay']);\n })\n );\n } else {\n Log::shouldReceive('info')->never();\n }\n\n /** @var Job&MockObject $job */\n $job = $this->createMock(Job::class);\n $job->method('attempts')->willReturn($attempts);\n $job->expects($this->once())->method('release');\n\n $next = static function (): void {\n throw new RateLimitException('rate limited', 1);\n };\n\n $this->middleware->handle($job, $next);\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.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"19","depth":4,"bounds":{"left":0.6296542,"top":0.10055866,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6409575,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.64827126,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","depth":4,"bounds":{"left":0.43018618,"top":0.09736632,"width":0.56981385,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {\n\"headers\":{\n\"Date\":[\"Thu,07 May 2026 14:21:15 GMT\"],\n \"Content-Type\":[\"application/json;charset=utf-8\"],\n \"Transfer-Encoding\":[\"chunked\"],\n \"Connection\":[\"keep-alive\"],\n \"CF-Ray\":[\"9f80deb8db60dc3a-SOF\"],\n \"CF-Cache-Status\":[\"DYNAMIC\"],\n \"Strict-Transport-Security\":[\"max-age=31536000; includeSubDomains; preload\"],\n \"Vary\":[\"origin,\n accept-encoding\"],\n \"access-control-allow-credentials\":[\"false\"],\n \"server-timing\":[\"hcid;desc=\\\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\\\",\n cfr;desc=\\\"9f80deb8e7c6dc3a-IAD\\\"\"],\n \"x-content-type-options\":[\"nosniff\"],\n \"x-hubspot-correlation-id\":[\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\"],\n \"Set-Cookie\":[\"__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-1.0.1.1-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,\n 07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None\"],\n \"Report-To\":[\"{\n\\\"endpoints\\\":[{\n\\\"url\\\":\\\"https:\\\\/\\\\/a.nel.cloudflare.com\\\\/report\\\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\\\"}],\n\\\"group\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"NEL\":[\"{\n\\\"success_fraction\\\":0.01,\n\\\"report_to\\\":\\\"cf-nel\\\",\n\\\"max_age\\\":604800}\"],\n\"Server\":[\"cloudflare\"]}} {\n\"correlation_id\":\"95236535-ec98-4541-b92a-adfa73b69eab\",\n\"trace_id\":\"c7ab8365-903f-46d4-9403-0e5b551e3545\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9091955119622055673
|
-2526499794819392950
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20725-handle-HS-search Project: faVsco.js, menu
JY-20725-handle-HS-search-rate-limit, menu
Start Listening for PHP Debug Connections
HandleHubspotRateLimitTest
Run 'HandleHubspotRateLimitTest'
Debug 'HandleHubspotRateLimitTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\Middleware;
use Exception;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
#[CoversClass(HandleHubspotRateLimit::class)]
class HandleHubspotRateLimitTest extends TestCase
{
private const int MAX_RETRY_DELAY = 600;
private const int MIN_RETRY_DELAY = 1;
private const int JITTER_SECONDS = 5;
private HandleHubspotRateLimit $middleware;
protected function setUp(): void
{
parent::setUp();
$this->middleware = new HandleHubspotRateLimit();
}
public function testPassesThroughWhenNoExceptionThrown(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$called = false;
$next = function (object $passed) use ($job, &$called): void {
$this->assertSame($job, $passed);
$called = true;
};
$this->middleware->handle($job, $next);
$this->assertTrue($called);
}
public function testPropagatesNonRateLimitExceptions(): void
{
$job = $this->createMock(Job::class);
$job->expects($this->never())->method('release');
$next = static function (): void {
throw new Exception('Database is down');
};
$this->expectException(Exception::class);
$this->expectExceptionMessage('Database is down');
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{retryAfter: int, expectedMin: int, expectedMax: int}>
*/
public static function delayClampingProvider(): array
{
return [
'short retry uses retry_after as floor' => [
'retryAfter' => 1,
'expectedMin' => self::MIN_RETRY_DELAY,
'expectedMax' => self::MIN_RETRY_DELAY + self::JITTER_SECONDS,
],
'medium retry passes through' => [
'retryAfter' => 30,
'expectedMin' => 30,
'expectedMax' => 30 + self::JITTER_SECONDS,
],
'large retry clamped to max' => [
'retryAfter' => 86400,
'expectedMin' => self::MAX_RETRY_DELAY,
'expectedMax' => self::MAX_RETRY_DELAY + self::JITTER_SECONDS,
],
];
}
#[DataProvider('delayClampingProvider')]
public function testReleasesJobWithClampedDelay(int $retryAfter, int $expectedMin, int $expectedMax): void
{
Log::shouldReceive('info')->zeroOrMoreTimes();
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn(1);
$job->expects($this->once())
->method('release')
->with($this->callback(static function (int $delay) use ($expectedMin, $expectedMax): bool {
return $delay >= $expectedMin && $delay <= $expectedMax;
}));
$next = static function () use ($retryAfter): void {
throw new RateLimitException('rate limited', $retryAfter);
};
$this->middleware->handle($job, $next);
}
/**
* @return array<string, array{attempts: int, shouldLog: bool}>
*/
public static function logSamplingProvider(): array
{
return [
'first attempt logs' => ['attempts' => 1, 'shouldLog' => true],
'second attempt logs' => ['attempts' => 2, 'shouldLog' => true],
'third attempt logs' => ['attempts' => 3, 'shouldLog' => true],
'fourth attempt skipped' => ['attempts' => 4, 'shouldLog' => false],
'ninth attempt skipped' => ['attempts' => 9, 'shouldLog' => false],
'tenth attempt logs (multiple of 10)' => ['attempts' => 10, 'shouldLog' => true],
'eleventh attempt skipped' => ['attempts' => 11, 'shouldLog' => false],
'twentieth attempt logs' => ['attempts' => 20, 'shouldLog' => true],
];
}
#[DataProvider('logSamplingProvider')]
public function testLogSampling(int $attempts, bool $shouldLog): void
{
if ($shouldLog) {
Log::shouldReceive('info')
->once()
->with(
'[HandleHubspotRateLimit] Rate limit caught, releasing job with delay',
$this->callback(static function (array $context) use ($attempts): bool {
return $context['attempts'] === $attempts
&& $context['retry_after'] === 1
&& isset($context['delay']);
})
);
} else {
Log::shouldReceive('info')->never();
}
/** @var Job&MockObject $job */
$job = $this->createMock(Job::class);
$job->method('attempts')->willReturn($attempts);
$job->expects($this->once())->method('release');
$next = static function (): void {
throw new RateLimitException('rate limited', 1);
};
$this->middleware->handle($job, $next);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
19
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 14:21:15] local.INFO: [Hubspot] DEBUG Getting headers {
"headers":{
"Date":["Thu,07 May 2026 14:21:15 GMT"],
"Content-Type":["application/json;charset=utf-8"],
"Transfer-Encoding":["chunked"],
"Connection":["keep-alive"],
"CF-Ray":["9f80deb8db60dc3a-SOF"],
"CF-Cache-Status":["DYNAMIC"],
"Strict-Transport-Security":["max-age=31536000; includeSubDomains; preload"],
"Vary":["origin,
accept-encoding"],
"access-control-allow-credentials":["false"],
"server-timing":["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",
cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],
"x-content-type-options":["nosniff"],
"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],
"Set-Cookie":["__cf_bm=SIUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-rI.ZggtDKxTge5zr8_2gbBfWMQQ.ufZEXDZyHz2mBUFdzdo2gTHEsOkXMSEShjK0hGYxNhUGM1ZoBpX7BcFZcHEjA7Cs_.SMUhUnd2nYjko; path=/; expires=Thu,
07-May-26 14:51:15 GMT; domain=.hubapi.com; HttpOnly; Secure; SameSite=None"],
"Report-To":["{
\"endpoints\":[{
\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RWRqiSp3wHsmdEgZlzoYdxI%2BIxVpHmsKn3O%2BKVA3mFIJ2m7YRECDGSM%2BW2IYTzo6FM4%2BdUIjURO8srzKSvJgZ%2BQ6R79arKQw3uHLlX\"}],
\"group\":\"cf-nel\",
\"max_age\":604800}"],
"NEL":["{
\"success_fraction\":0.01,
\"report_to\":\"cf-nel\",
\"max_age\":604800}"],
"Server":["cloudflare"]}} {
"correlation_id":"95236535-ec98-4541-b92a-adfa73b69eab",
"trace_id":"c7ab8365-903f-46d4-9403-0e5b551e3545"}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
1455
|
57
|
15
|
2026-05-07T08:44:29.207033+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778143469207_m1.jpg...
|
PhpStorm
|
faVsco.js – DeleteCrmEntityTrait.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Code changed:
Hide
Sync Changes
Hide This Notification
37
1
35
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
Sync Changes
Hide This Notification
Code changed:
Hide
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Crm\Delete;
use Illuminate\Events\Dispatcher;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Jiminny\Enums\CrmObject;
use Jiminny\Events\Crm\DetachActivityObject;
use Jiminny\Models\Activity;
use Psr\Log\LoggerInterface;
use Throwable;
trait DeleteCrmEntityTrait
{
public int $tries = 3;
public function timeout(): int
{
return 300; // 5 minutes
}
public function backoff(): array
{
return [30, 90, 180]; // 30 seconds, 1.5 minutes, 3 minutes
}
protected function handleActivities(
Collection $activities,
Dispatcher $dispatcher,
LoggerInterface $logger,
bool $emitEvent = true,
): void {
if ($activities->isEmpty()) {
return;
}
$crmObject = $this->getEntityType();
$entityIdField = $crmObject->value . '_id';
$activities->each(
function (Activity $activity) use ($dispatcher, $logger, $entityIdField, $crmObject, $emitEvent): void {
$stageId = $activity->getStage()?->getId();
$logData = [
$crmObject->value => $this->id,
'activity' => $activity->getId(),
'emitEvent' => $emitEvent,
];
$updateData = [
$entityIdField => null,
];
// For leads and opportunities, also nullify the stage_id
if ($stageId && in_array($crmObject, [CrmObject::LEAD, CrmObject::OPPORTUNITY], true)) {
$updateData['stage_id'] = null;
$logData['stage_id'] = $stageId;
}
$activity->update($updateData);
if ($emitEvent) {
$dispatcher->dispatch(new DetachActivityObject($activity, $crmObject));
}
$logger->info($this->getLogPrefix() . ' Detach from activity', $logData);
// Dispatch job to verify if CRM task/event still exists
if ($activity->hasCrmProviderId()) {
VerifyActivityCrmTaskJob::dispatch($activity->getId());
}
}
);
}
public function failed(Throwable $exception): void
{
$crmObject = $this->getEntityType();
Log::critical($this->getLogPrefix() . ' Job failed permanently', [
$crmObject->value => $this->id,
'exception' => $exception->getMessage(),
]);
}
// Abstract methods that must be implemented by the using class
abstract protected function getLogPrefix(): string;
abstract protected function getEntityType(): CrmObject;
}
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
AiActivityType, folder
AiAutomation, folder
AiCallScoring, folder
AskAnything, folder
Dtos, folder
Events, folder
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi, folder
AWS, folder
BillingManagement, folder
Cache, folder
CoachingFeedback, folder
Country, folder
CustomerApi, folder
Database, folder
Datadog, folder
DateTime, folder
DealInsights, folder
DealRisks, folder
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection, folder
LiveFeed, folder
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue
Job
RateLimitAware.php, abstract class
RateLimitAwareWrapper.php, class
BotsQueueConstants.php, class
Constants.php, class
ProcessingQueueConstants.php, class
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary
Twilio
Uploader
UrlGenerator
Utility
Exceptions
Service
BaseRateLimiter.php, class
EfficientJsonParser.php, class
ProviderRateLimiter.php, class
RateLimiterInstance.php, class
Uuid
Waveform
Webhooks
Workflow
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
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
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"37","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"35","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;","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.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Crm\\Delete;\n\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Enums\\CrmObject;\nuse Jiminny\\Events\\Crm\\DetachActivityObject;\nuse Jiminny\\Models\\Activity;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\ntrait DeleteCrmEntityTrait\n{\n public int $tries = 3;\n\n public function timeout(): int\n {\n return 300; // 5 minutes\n }\n\n public function backoff(): array\n {\n return [30, 90, 180]; // 30 seconds, 1.5 minutes, 3 minutes\n }\n\n protected function handleActivities(\n Collection $activities,\n Dispatcher $dispatcher,\n LoggerInterface $logger,\n bool $emitEvent = true,\n ): void {\n if ($activities->isEmpty()) {\n return;\n }\n\n $crmObject = $this->getEntityType();\n $entityIdField = $crmObject->value . '_id';\n\n $activities->each(\n function (Activity $activity) use ($dispatcher, $logger, $entityIdField, $crmObject, $emitEvent): void {\n $stageId = $activity->getStage()?->getId();\n\n $logData = [\n $crmObject->value => $this->id,\n 'activity' => $activity->getId(),\n 'emitEvent' => $emitEvent,\n ];\n\n $updateData = [\n $entityIdField => null,\n ];\n\n // For leads and opportunities, also nullify the stage_id\n if ($stageId && in_array($crmObject, [CrmObject::LEAD, CrmObject::OPPORTUNITY], true)) {\n $updateData['stage_id'] = null;\n $logData['stage_id'] = $stageId;\n }\n\n $activity->update($updateData);\n\n if ($emitEvent) {\n $dispatcher->dispatch(new DetachActivityObject($activity, $crmObject));\n }\n\n $logger->info($this->getLogPrefix() . ' Detach from activity', $logData);\n\n // Dispatch job to verify if CRM task/event still exists\n if ($activity->hasCrmProviderId()) {\n VerifyActivityCrmTaskJob::dispatch($activity->getId());\n }\n }\n );\n }\n\n public function failed(Throwable $exception): void\n {\n $crmObject = $this->getEntityType();\n\n Log::critical($this->getLogPrefix() . ' Job failed permanently', [\n $crmObject->value => $this->id,\n 'exception' => $exception->getMessage(),\n ]);\n }\n\n // Abstract methods that must be implemented by the using class\n abstract protected function getLogPrefix(): string;\n abstract protected function getEntityType(): CrmObject;\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Crm\\Delete;\n\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Enums\\CrmObject;\nuse Jiminny\\Events\\Crm\\DetachActivityObject;\nuse Jiminny\\Models\\Activity;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\ntrait DeleteCrmEntityTrait\n{\n public int $tries = 3;\n\n public function timeout(): int\n {\n return 300; // 5 minutes\n }\n\n public function backoff(): array\n {\n return [30, 90, 180]; // 30 seconds, 1.5 minutes, 3 minutes\n }\n\n protected function handleActivities(\n Collection $activities,\n Dispatcher $dispatcher,\n LoggerInterface $logger,\n bool $emitEvent = true,\n ): void {\n if ($activities->isEmpty()) {\n return;\n }\n\n $crmObject = $this->getEntityType();\n $entityIdField = $crmObject->value . '_id';\n\n $activities->each(\n function (Activity $activity) use ($dispatcher, $logger, $entityIdField, $crmObject, $emitEvent): void {\n $stageId = $activity->getStage()?->getId();\n\n $logData = [\n $crmObject->value => $this->id,\n 'activity' => $activity->getId(),\n 'emitEvent' => $emitEvent,\n ];\n\n $updateData = [\n $entityIdField => null,\n ];\n\n // For leads and opportunities, also nullify the stage_id\n if ($stageId && in_array($crmObject, [CrmObject::LEAD, CrmObject::OPPORTUNITY], true)) {\n $updateData['stage_id'] = null;\n $logData['stage_id'] = $stageId;\n }\n\n $activity->update($updateData);\n\n if ($emitEvent) {\n $dispatcher->dispatch(new DetachActivityObject($activity, $crmObject));\n }\n\n $logger->info($this->getLogPrefix() . ' Detach from activity', $logData);\n\n // Dispatch job to verify if CRM task/event still exists\n if ($activity->hasCrmProviderId()) {\n VerifyActivityCrmTaskJob::dispatch($activity->getId());\n }\n }\n );\n }\n\n public function failed(Throwable $exception): void\n {\n $crmObject = $this->getEntityType();\n\n Log::critical($this->getLogPrefix() . ' Job failed permanently', [\n $crmObject->value => $this->id,\n 'exception' => $exception->getMessage(),\n ]);\n }\n\n // Abstract methods that must be implemented by the using class\n abstract protected function getLogPrefix(): string;\n abstract protected function getEntityType(): CrmObject;\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Job","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitAware.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitAwareWrapper.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BotsQueueConstants.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Constants.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessingQueueConstants.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Exceptions","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Service","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BaseRateLimiter.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EfficientJsonParser.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProviderRateLimiter.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimiterInstance.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"}]...
|
-9089949279098730604
|
1065696262816675397
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Code changed:
Hide
Sync Changes
Hide This Notification
37
1
35
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
Sync Changes
Hide This Notification
Code changed:
Hide
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Crm\Delete;
use Illuminate\Events\Dispatcher;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Jiminny\Enums\CrmObject;
use Jiminny\Events\Crm\DetachActivityObject;
use Jiminny\Models\Activity;
use Psr\Log\LoggerInterface;
use Throwable;
trait DeleteCrmEntityTrait
{
public int $tries = 3;
public function timeout(): int
{
return 300; // 5 minutes
}
public function backoff(): array
{
return [30, 90, 180]; // 30 seconds, 1.5 minutes, 3 minutes
}
protected function handleActivities(
Collection $activities,
Dispatcher $dispatcher,
LoggerInterface $logger,
bool $emitEvent = true,
): void {
if ($activities->isEmpty()) {
return;
}
$crmObject = $this->getEntityType();
$entityIdField = $crmObject->value . '_id';
$activities->each(
function (Activity $activity) use ($dispatcher, $logger, $entityIdField, $crmObject, $emitEvent): void {
$stageId = $activity->getStage()?->getId();
$logData = [
$crmObject->value => $this->id,
'activity' => $activity->getId(),
'emitEvent' => $emitEvent,
];
$updateData = [
$entityIdField => null,
];
// For leads and opportunities, also nullify the stage_id
if ($stageId && in_array($crmObject, [CrmObject::LEAD, CrmObject::OPPORTUNITY], true)) {
$updateData['stage_id'] = null;
$logData['stage_id'] = $stageId;
}
$activity->update($updateData);
if ($emitEvent) {
$dispatcher->dispatch(new DetachActivityObject($activity, $crmObject));
}
$logger->info($this->getLogPrefix() . ' Detach from activity', $logData);
// Dispatch job to verify if CRM task/event still exists
if ($activity->hasCrmProviderId()) {
VerifyActivityCrmTaskJob::dispatch($activity->getId());
}
}
);
}
public function failed(Throwable $exception): void
{
$crmObject = $this->getEntityType();
Log::critical($this->getLogPrefix() . ' Job failed permanently', [
$crmObject->value => $this->id,
'exception' => $exception->getMessage(),
]);
}
// Abstract methods that must be implemented by the using class
abstract protected function getLogPrefix(): string;
abstract protected function getEntityType(): CrmObject;
}
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
AiActivityType, folder
AiAutomation, folder
AiCallScoring, folder
AskAnything, folder
Dtos, folder
Events, folder
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi, folder
AWS, folder
BillingManagement, folder
Cache, folder
CoachingFeedback, folder
Country, folder
CustomerApi, folder
Database, folder
Datadog, folder
DateTime, folder
DealInsights, folder
DealRisks, folder
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection, folder
LiveFeed, folder
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue
Job
RateLimitAware.php, abstract class
RateLimitAwareWrapper.php, class
BotsQueueConstants.php, class
Constants.php, class
ProcessingQueueConstants.php, class
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary
Twilio
Uploader
UrlGenerator
Utility
Exceptions
Service
BaseRateLimiter.php, class
EfficientJsonParser.php, class
ProviderRateLimiter.php, class
RateLimiterInstance.php, class
Uuid
Waveform
Webhooks
Workflow
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
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
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class...
|
1451
|
NULL
|
NULL
|
NULL
|
|
18020
|
782
|
35
|
2026-05-11T10:45:38.741152+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778496338741_m1.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER181DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER181DEV (docker)$2APP (-zsh)883viewsjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00: stoppedjiminny-worker-processing-4: jiminny-worker-processing-4_00: stoppedJiminny-worker-processing-5:j1minny-worker-processing-5_00:jiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-emails:worker-emails_00: stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00:jiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny:debugDispatching 100 MatchActivityCrmData jobs (portal=2)Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.root@docker_lamp_1:/home/jiminny# php artisan jiminny:debugDispatching 100 MatchActivityCrmData jobs (portal=2)Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.root@docker_lamp_1:/home/jiminny# ]DEV (d)-zshHomeDMsActivityFilesLater..•Morelthl• Support Daily • in 1h 15 m100% <78• Mon 11 May 13:45:38ED→Describe what you are looking forJiminny ...# contusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...ToastHomeMessages^ Direct messages®. Aneliya Angelova®. Galya Dimitrova& Petko Kashinski&. Stefka StoyanovaVasil Vasilev OlC. Nikolay IvanovAneliya Angelova, ...Stoyan Tanev®. VesE Lukas Kovalik y... 0AboutiminnyFriday, May 8th ~Added by Toast for GitHubToday ~Toast APP10:00 AMReviewapp#12059 Jy 20820 es reindexstream model hydration2 days old • 12 files changed •@Vasil VasilevAdded by Toast for GitHubResolve Conflictsapp#11443 Test hublets latency5 months old • 20 files changed#11327 JY-19501 webhookbased opportunity syncShow moreAdded by Toast for GitHubNeeds Loveapp#12024 JY-20773 fix user pilottracking ofr automated reportgenerated12 days old • 1 file changedE:: AppsMessage ToastJira CloudToast+AaConala CalaNew...
|
NULL
|
-9089781524009160870
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpDOCKER181DEV ( SlackFileEditViewGoHistoryWindowHelpDOCKER181DEV (docker)$2APP (-zsh)883viewsjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00: stoppedjiminny-worker-processing-4: jiminny-worker-processing-4_00: stoppedJiminny-worker-processing-5:j1minny-worker-processing-5_00:jiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-emails:worker-emails_00: stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00:jiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny:debugDispatching 100 MatchActivityCrmData jobs (portal=2)Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.root@docker_lamp_1:/home/jiminny# php artisan jiminny:debugDispatching 100 MatchActivityCrmData jobs (portal=2)Done. Watch logs and run jiminny:debug observeRateLimit to inspect cache state.root@docker_lamp_1:/home/jiminny# ]DEV (d)-zshHomeDMsActivityFilesLater..•Morelthl• Support Daily • in 1h 15 m100% <78• Mon 11 May 13:45:38ED→Describe what you are looking forJiminny ...# contusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...ToastHomeMessages^ Direct messages®. Aneliya Angelova®. Galya Dimitrova& Petko Kashinski&. Stefka StoyanovaVasil Vasilev OlC. Nikolay IvanovAneliya Angelova, ...Stoyan Tanev®. VesE Lukas Kovalik y... 0AboutiminnyFriday, May 8th ~Added by Toast for GitHubToday ~Toast APP10:00 AMReviewapp#12059 Jy 20820 es reindexstream model hydration2 days old • 12 files changed •@Vasil VasilevAdded by Toast for GitHubResolve Conflictsapp#11443 Test hublets latency5 months old • 20 files changed#11327 JY-19501 webhookbased opportunity syncShow moreAdded by Toast for GitHubNeeds Loveapp#12024 JY-20773 fix user pilottracking ofr automated reportgenerated12 days old • 1 file changedE:: AppsMessage ToastJira CloudToast+AaConala CalaNew...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
12329
|
545
|
28
|
2026-05-09T08:46:51.324167+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778316411324_m1.jpg...
|
Firefox
|
It's time to check in! - kovaliklukas@gmail.co It's time to check in! - kovaliklukas@gmail.com - Gmail — Personal...
|
True
|
mail.google.com/mail/u/0/#inbox/FMfcgzQgLjRqXXkbRv mail.google.com/mail/u/0/#inbox/FMfcgzQgLjRqXXkbRvTVxJWDgMKcCVrL...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
It's time to check in! - [EMAIL] - Gmail
It's time to check in! - [EMAIL] - Gmail
Close tab
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Select: payments - db - Adminer
Select: payments - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
None selected
Skip to content
Skip to content
Using Gmail with screen readers
Using Gmail with screen readers
Main menu
Gmail
Search
Search
Search mail
Advanced search options
Search mail
Support
Settings
Ask Gemini
Google apps
Google Account: Lukáš Koválik ([EMAIL])
Compose
Labels
Labels
Inbox 28 unread
Inbox
28
Starred
Starred
Snoozed
Snoozed
Important
Important
Sent
Sent
Drafts 8 unread
Drafts
8
Purchases has menu
Purchases
Social 5202 unread has menu
Social
5,202
Updates 8790 unread has menu
Updates
8,790
Forums 6100 unread has menu
Forums
6,100
Promotions 38752 unread has menu
Promotions
38,752
More labels
More
Labels
Labels
Create new label
Labels
Labels
[Imap]/Nevyžiadaná pošta has menu
[Imap]/Nevyžiadaná pošta
arch has menu
arch
Deleted Items has menu
Deleted Items
Fibank 1229 unread has menu
Fibank
1,229
FL 6 unread has menu
FL
6
Hardware & Software has menu
Hardware & Software
HOSTING 5 unread has menu
HOSTING
5
Infected Items has menu
Infected Items
jiminny-github 7487 unread has menu
jiminny-github
7,487
Junk E-mail 219 unread has menu
Junk E-mail
219
Kontakty has menu
Kontakty
Sent Items has menu
Sent Items
WORK 848 unread has menu
WORK
848
z centra 1274 unread has menu
z centra
1,274
More labels
More
Back to Inbox
Archive
Report spam
Delete
Mark as unread
Move to
More email options
31
of
21,245
Newer
Older
Input tools on/off (Ctrl-Shift-K)
Select input tool
Print all
In new window
It's time to check in!
It's time to check in!
Important according to Google magic
Search for all messages with label Inbox
Remove label Inbox from this conversation
Wizz Air [EMAIL]
Wizz Air [EMAIL]
Wizz Air
[EMAIL]
Tue 5 May, 14:21 (4 days ago)
Tue 5 May, 14:21 (4 days ago)
Not starred
Add reaction
Reply
More message options
to
me
Show details
Wizz Air Logo
wizzair facebook
wizzair X
wizzair instagram
wizzair youtube
wizzair linkedin
MANAGE MY BOOKING
MANAGE MY BOOKING
|
FLIGHTS
FLIGHTS
|
HOTEL
HOTEL
|
CAR RENTALS
CAR RENTALS
|
TRANSFER
TRANSFER
|
PARKING
PARKING
Time to check in
Confirmation number:
YTPB8R
Dear Passenger,
Your Wizz Air flight is coming up soon! Please remember to check in online, and kindly note that
this service is free of charge on our website or via our mobile app up to three hours before departure.
At the airport a fee will be applied, unless you purchased the airport check-in service with your booking.
CHECK IN ONLINE
CHECK IN ONLINE
Please note:
At the airports where mobile or online check-in are not yet available, Wizz Air provides airport check-in service free of charge. In all other cases airport check-in fee will be charged. For all details and exceptions visit our
dedicated website page.
dedicated website page.
Once you’ve checked in, all you need to do is
present the boarding card on your mobile device at the check-in desk or gate. This is available in the WIZZ mobile app or website
and does not need to be printed except if required by the departure airport –
see the list of such airports here.
see the list of such airports here.
Download Wizz Air app
There is no more “I have no idea where I last saw my boarding card”, because it’s always at hand. Amazing, isn’t it?
Download Wizz Air mobile app with the QR code for easier and more enjoyable travel experience!
download Wizz Air app QR code
One more thing! You will still be able to modify your reservation and purchase additional services even after completing the online check-in.
We wish you a safe trip!
Best regards,
The Wizz Air Team
This message is from Wizz Air Hungary Ltd.
Postal address: Lechner Ödön fasor 6. Millenium Tower I., 1095, Budapest, Hungary
Metropolitan Court as Court of Registration, Reg.No.: 01-10-140174.
Tax number: 26648525-2-44.
Privacy notice
Your privacy is important to us. You can read more about our Privacy notice
here
here
.
...
[Message clipped]
View entire message
View entire message
Reply
Reply
Forward
Forward
Add reaction
Calendar
Keep
Tasks
Contacts
Get add-ons
Hide side panel...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DNS / Nameservers | Hostinger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DNS / Nameservers | Hostinger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: archive.db","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: db.sqlite","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AFFiNE - All In One KnowledgeOS","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AFFiNE - All In One KnowledgeOS","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All docs · AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Payments Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"It's time to check in! - kovaliklukas@gmail.com - Gmail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"It's time to check in! - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"(25) Quora","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(25) Quora","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Select: payments - db - Adminer","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select: payments - db - Adminer","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"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.13229166,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.15520833,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.17847222,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.20173611,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.225,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"None selected","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to content","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Using Gmail with screen readers","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Using Gmail with screen readers","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Main menu","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXLink","text":"Gmail","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Search","depth":12,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search mail","depth":18,"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Advanced search options","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search mail","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Support","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Settings","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Gemini","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Google apps","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Google Account: Lukáš Koválik (kovaliklukas@gmail.com)","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Compose","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Labels","depth":12,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Labels","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Inbox 28 unread","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"28","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Starred","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Starred","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Snoozed","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Snoozed","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Important","depth":17,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Important","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sent","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sent","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Drafts 8 unread","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Drafts","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Purchases has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Purchases","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Social 5202 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Social","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5,202","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Updates 8790 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Updates","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8,790","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Forums 6100 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Forums","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6,100","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Promotions 38752 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Promotions","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"38,752","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More labels","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"More","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Labels","depth":11,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Labels","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create new label","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Labels","depth":12,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Labels","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"[Imap]/Nevyžiadaná pošta has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Imap]/Nevyžiadaná pošta","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"arch has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"arch","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deleted Items has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deleted Items","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Fibank 1229 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fibank","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1,229","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"FL 6 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"FL","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Hardware & Software has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hardware & Software","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"HOSTING 5 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"HOSTING","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Infected Items has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Infected Items","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jiminny-github 7487 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny-github","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7,487","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Junk E-mail 219 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Junk E-mail","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"219","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Kontakty has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kontakty","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sent Items has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sent Items","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"WORK 848 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"WORK","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"848","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"z centra 1274 unread has menu","depth":16,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"z centra","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1,274","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More labels","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"More","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Back to Inbox","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Archive","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Report spam","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Delete","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mark as unread","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Move to","depth":11,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"More email options","depth":11,"on_screen":true,"help_text":"More","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"31","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"of","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21,245","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Newer","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Older","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Input tools on/off (Ctrl-Shift-K)","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Select input tool","depth":11,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Print all","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"In new window","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"It's time to check in!","depth":13,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"It's time to check in!","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Important according to Google magic","depth":14,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search for all messages with label Inbox","depth":15,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Remove label Inbox from this conversation","depth":15,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Wizz Air offers@noreply.wizznews.com","depth":23,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXCell","text":"Wizz Air offers@noreply.wizznews.com","depth":24,"on_screen":true,"help_text":"","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Wizz Air","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"offers@noreply.wizznews.com","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCell","text":"Tue 5 May, 14:21 (4 days ago)","depth":20,"on_screen":true,"help_text":"5 May 2026, 14:21","role_description":"cell","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tue 5 May, 14:21 (4 days ago)","depth":21,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Not starred","depth":21,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Add reaction","depth":21,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Reply","depth":21,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More message options","depth":22,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"to","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"me","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Show details","depth":23,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Wizz Air Logo","depth":26,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"wizzair facebook","depth":27,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"wizzair X","depth":28,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"wizzair instagram","depth":28,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"wizzair youtube","depth":28,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"wizzair linkedin","depth":28,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"MANAGE MY BOOKING","depth":25,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MANAGE MY BOOKING","depth":27,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"FLIGHTS","depth":25,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"FLIGHTS","depth":27,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"HOTEL","depth":25,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"HOTEL","depth":27,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CAR RENTALS","depth":25,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CAR RENTALS","depth":27,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"TRANSFER","depth":25,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TRANSFER","depth":27,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"PARKING","depth":25,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PARKING","depth":27,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Time to check in","depth":26,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Confirmation number:","depth":26,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"YTPB8R","depth":27,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dear Passenger,","depth":26,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your Wizz Air flight is coming up soon! Please remember to check in online, and kindly note that","depth":26,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this service is free of charge on our website or via our mobile app up to three hours before departure.","depth":27,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"At the airport a fee will be applied, unless you purchased the airport check-in service with your booking.","depth":26,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CHECK IN ONLINE","depth":25,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CHECK IN ONLINE","depth":26,"bounds":{"left":0.95208335,"top":0.0,"width":0.04791665,"height":0.02388889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Please note:","depth":29,"bounds":{"left":0.87395835,"top":0.0055555557,"width":0.061805554,"height":0.02111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"At the airports where mobile or online check-in are not yet available, Wizz Air provides airport check-in service free of charge. In all other cases airport check-in fee will be charged. For all details and exceptions visit our","depth":28,"bounds":{"left":0.87395835,"top":0.0055555557,"width":0.12604165,"height":0.101111114},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"dedicated website page.","depth":28,"bounds":{"left":1.0,"top":0.08555555,"width":-0.04340279,"height":0.02111111},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"dedicated website page.","depth":29,"bounds":{"left":1.0,"top":0.08555555,"width":-0.04340279,"height":0.02111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Once you’ve checked in, all you need to do is","depth":26,"bounds":{"left":0.8076389,"top":0.16777778,"width":0.19236112,"height":0.02111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"present the boarding card on your mobile device at the check-in desk or gate. This is available in the WIZZ mobile app or website","depth":27,"bounds":{"left":0.8076389,"top":0.16777778,"width":0.19236112,"height":0.07444444},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and does not need to be printed except if required by the departure airport –","depth":26,"bounds":{"left":0.8076389,"top":0.2211111,"width":0.19236112,"height":0.04777778},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"see the list of such airports here.","depth":26,"bounds":{"left":0.853125,"top":0.24777777,"width":0.14687502,"height":0.02111111},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"see the list of such airports here.","depth":27,"bounds":{"left":0.853125,"top":0.24777777,"width":0.14687502,"height":0.02111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Download Wizz Air app","depth":26,"bounds":{"left":0.928125,"top":0.31611112,"width":0.071874976,"height":0.031666666},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"There is no more “I have no idea where I last saw my boarding card”, because it’s always at hand. Amazing, isn’t it?","depth":26,"bounds":{"left":0.8076389,"top":0.39444444,"width":0.19236112,"height":0.07444444},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Download Wizz Air mobile app with the QR code for easier and more enjoyable travel experience!","depth":27,"bounds":{"left":0.8076389,"top":0.44777778,"width":0.19236112,"height":0.04777778},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"download Wizz Air app QR code","depth":27,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"One more thing! You will still be able to modify your reservation and purchase additional services even after completing the online check-in.","depth":26,"bounds":{"left":0.8076389,"top":0.56333333,"width":0.19236112,"height":0.04777778},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"We wish you a safe trip!","depth":26,"bounds":{"left":0.8076389,"top":0.6433333,"width":0.11666667,"height":0.02111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Best regards,","depth":26,"bounds":{"left":0.8076389,"top":0.7033333,"width":0.06458333,"height":0.02111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Wizz Air Team","depth":27,"bounds":{"left":0.8076389,"top":0.73,"width":0.09375,"height":0.02111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This message is from Wizz Air Hungary Ltd.","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Postal address: Lechner Ödön fasor 6. Millenium Tower I., 1095, Budapest, Hungary","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Metropolitan Court as Court of Registration, Reg.No.: 01-10-140174.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tax number: 26648525-2-44.","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Privacy notice","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your privacy is important to us. You can read more about our Privacy notice","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"here","depth":28,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"here","depth":29,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"...","depth":21,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[Message clipped]","depth":21,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View entire message","depth":21,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View entire message","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reply","depth":14,"bounds":{"left":0.59166664,"top":0.0,"width":0.072222225,"height":0.04},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reply","depth":15,"bounds":{"left":0.6232639,"top":0.0,"width":0.025694445,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Forward","depth":14,"bounds":{"left":0.66944444,"top":0.0,"width":0.07777778,"height":0.04},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Forward","depth":15,"bounds":{"left":0.6979167,"top":0.0,"width":0.0375,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add reaction","depth":15,"bounds":{"left":0.75277776,"top":0.0,"width":0.025,"height":0.04},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Calendar","depth":10,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Keep","depth":10,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Tasks","depth":10,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Contacts","depth":10,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Get add-ons","depth":10,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Hide side panel","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-9089034085152746233
|
-396962890767626853
|
click
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
It's time to check in! - [EMAIL] - Gmail
It's time to check in! - [EMAIL] - Gmail
Close tab
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Select: payments - db - Adminer
Select: payments - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
None selected
Skip to content
Skip to content
Using Gmail with screen readers
Using Gmail with screen readers
Main menu
Gmail
Search
Search
Search mail
Advanced search options
Search mail
Support
Settings
Ask Gemini
Google apps
Google Account: Lukáš Koválik ([EMAIL])
Compose
Labels
Labels
Inbox 28 unread
Inbox
28
Starred
Starred
Snoozed
Snoozed
Important
Important
Sent
Sent
Drafts 8 unread
Drafts
8
Purchases has menu
Purchases
Social 5202 unread has menu
Social
5,202
Updates 8790 unread has menu
Updates
8,790
Forums 6100 unread has menu
Forums
6,100
Promotions 38752 unread has menu
Promotions
38,752
More labels
More
Labels
Labels
Create new label
Labels
Labels
[Imap]/Nevyžiadaná pošta has menu
[Imap]/Nevyžiadaná pošta
arch has menu
arch
Deleted Items has menu
Deleted Items
Fibank 1229 unread has menu
Fibank
1,229
FL 6 unread has menu
FL
6
Hardware & Software has menu
Hardware & Software
HOSTING 5 unread has menu
HOSTING
5
Infected Items has menu
Infected Items
jiminny-github 7487 unread has menu
jiminny-github
7,487
Junk E-mail 219 unread has menu
Junk E-mail
219
Kontakty has menu
Kontakty
Sent Items has menu
Sent Items
WORK 848 unread has menu
WORK
848
z centra 1274 unread has menu
z centra
1,274
More labels
More
Back to Inbox
Archive
Report spam
Delete
Mark as unread
Move to
More email options
31
of
21,245
Newer
Older
Input tools on/off (Ctrl-Shift-K)
Select input tool
Print all
In new window
It's time to check in!
It's time to check in!
Important according to Google magic
Search for all messages with label Inbox
Remove label Inbox from this conversation
Wizz Air [EMAIL]
Wizz Air [EMAIL]
Wizz Air
[EMAIL]
Tue 5 May, 14:21 (4 days ago)
Tue 5 May, 14:21 (4 days ago)
Not starred
Add reaction
Reply
More message options
to
me
Show details
Wizz Air Logo
wizzair facebook
wizzair X
wizzair instagram
wizzair youtube
wizzair linkedin
MANAGE MY BOOKING
MANAGE MY BOOKING
|
FLIGHTS
FLIGHTS
|
HOTEL
HOTEL
|
CAR RENTALS
CAR RENTALS
|
TRANSFER
TRANSFER
|
PARKING
PARKING
Time to check in
Confirmation number:
YTPB8R
Dear Passenger,
Your Wizz Air flight is coming up soon! Please remember to check in online, and kindly note that
this service is free of charge on our website or via our mobile app up to three hours before departure.
At the airport a fee will be applied, unless you purchased the airport check-in service with your booking.
CHECK IN ONLINE
CHECK IN ONLINE
Please note:
At the airports where mobile or online check-in are not yet available, Wizz Air provides airport check-in service free of charge. In all other cases airport check-in fee will be charged. For all details and exceptions visit our
dedicated website page.
dedicated website page.
Once you’ve checked in, all you need to do is
present the boarding card on your mobile device at the check-in desk or gate. This is available in the WIZZ mobile app or website
and does not need to be printed except if required by the departure airport –
see the list of such airports here.
see the list of such airports here.
Download Wizz Air app
There is no more “I have no idea where I last saw my boarding card”, because it’s always at hand. Amazing, isn’t it?
Download Wizz Air mobile app with the QR code for easier and more enjoyable travel experience!
download Wizz Air app QR code
One more thing! You will still be able to modify your reservation and purchase additional services even after completing the online check-in.
We wish you a safe trip!
Best regards,
The Wizz Air Team
This message is from Wizz Air Hungary Ltd.
Postal address: Lechner Ödön fasor 6. Millenium Tower I., 1095, Budapest, Hungary
Metropolitan Court as Court of Registration, Reg.No.: 01-10-140174.
Tax number: 26648525-2-44.
Privacy notice
Your privacy is important to us. You can read more about our Privacy notice
here
here
.
...
[Message clipped]
View entire message
View entire message
Reply
Reply
Forward
Forward
Add reaction
Calendar
Keep
Tasks
Contacts
Get add-ons
Hide side panel...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
8257
|
366
|
3
|
2026-05-08T10:15:46.955796+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-08/1778 /Users/lukas/.screenpipe/data/data/2026-05-08/1778235346955_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
It's the only usage in Project Files
Find Opti It's the only usage in Project Files
Find Options… (⌃⌥⌘N)
text/html
text/html
text/html
text/html
text/html
Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
69
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
// First try to get Retry-After from response headers
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
// For search APIs, headers are often missing - check response body for policyName
if (method_exists($e, 'getResponseBody')) {
$body = $e->getResponseBody();
if (is_string($body)) {
$body = json_decode($body, true) ?? [];
}
$policyName = $body['policyName'] ?? $body['policy'] ?? null;
// Map policy names to retry delays
if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {
return 10;
}
if ($policyName === 'SECONDLY' || $policyName === 'secondly') {
return 1;
}
}
// Also check nested context object if present
if (method_exists($e, 'getResponseBody')) {
$body = $e->getResponseBody();
if (is_string($body)) {
$body = json_decode($body, true) ?? [];
}
$context = $body['context'] ?? [];
$policyName = $context['policyName'] ?? null;
if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {
return 10;
}
if ($policyName === 'SECONDLY' || $policyName === 'secondly') {
return 1;
}
}
$this->log->debug('[Hubspot] No retry-after header or policy name found, using default', [
'exception_class' => get_class($e),
]);
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* Execute a search request against HubSpot CRM objects with rate limiting.
*
* @param string $objectType The object type ('deals', 'companies', 'contacts', 'calls')
* @param array<string, mixed> $payload The search payload with filters, sorts, properties, etc.
* @return array The search response with 'results', 'total', 'paging' keys
* @throws RateLimitException When rate limit is hit
* @throws HubspotException On API errors
*/
public function search(string $objectType, array $payload): array
{
$endpoint = self::BASE_URL . "/crm/v3/objects/{$objectType}/search";
return $this->executeRequest(function () use ($endpoint, $payload) {
$response = $this->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
});
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…...
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"It's the only usage in Project Files\nFind Options… (⌃⌥⌘N)","depth":2,"bounds":{"left":0.17885639,"top":0.38467678,"width":0.06815159,"height":0.027134877},"on_screen":true,"value":"It's the only usage in Project Files\nFind Options… (⌃⌥⌘N)","help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"text/html","depth":3,"on_screen":false,"help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"text/html","depth":3,"bounds":{"left":0.17885639,"top":0.38467678,"width":0.06815159,"height":0.013567438},"on_screen":true,"help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"text/html","depth":3,"bounds":{"left":0.17885639,"top":0.3982442,"width":0.029587766,"height":0.013567438},"on_screen":true,"help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"text/html","depth":3,"bounds":{"left":0.20844415,"top":0.3982442,"width":0.019946808,"height":0.013567438},"on_screen":true,"help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"text/html","depth":3,"on_screen":false,"help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.33776596,"top":0.12529927,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.34773937,"top":0.12529927,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3600399,"top":0.12529927,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.36901596,"top":0.123703115,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.37632978,"top":0.123703115,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n // First try to get Retry-After from response headers\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n // For search APIs, headers are often missing - check response body for policyName\n if (method_exists($e, 'getResponseBody')) {\n $body = $e->getResponseBody();\n if (is_string($body)) {\n $body = json_decode($body, true) ?? [];\n }\n $policyName = $body['policyName'] ?? $body['policy'] ?? null;\n\n // Map policy names to retry delays\n if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {\n return 10;\n }\n if ($policyName === 'SECONDLY' || $policyName === 'secondly') {\n return 1;\n }\n }\n\n // Also check nested context object if present\n if (method_exists($e, 'getResponseBody')) {\n $body = $e->getResponseBody();\n if (is_string($body)) {\n $body = json_decode($body, true) ?? [];\n }\n $context = $body['context'] ?? [];\n $policyName = $context['policyName'] ?? null;\n\n if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {\n return 10;\n }\n if ($policyName === 'SECONDLY' || $policyName === 'secondly') {\n return 1;\n }\n }\n\n $this->log->debug('[Hubspot] No retry-after header or policy name found, using default', [\n 'exception_class' => get_class($e),\n ]);\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * Execute a search request against HubSpot CRM objects with rate limiting.\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts', 'calls')\n * @param array<string, mixed> $payload The search payload with filters, sorts, properties, etc.\n * @return array The search response with 'results', 'total', 'paging' keys\n * @throws RateLimitException When rate limit is hit\n * @throws HubspotException On API errors\n */\n public function search(string $objectType, array $payload): array\n {\n $endpoint = self::BASE_URL . \"/crm/v3/objects/{$objectType}/search\";\n\n return $this->executeRequest(function () use ($endpoint, $payload) {\n $response = $this->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n });\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n // First try to get Retry-After from response headers\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n // For search APIs, headers are often missing - check response body for policyName\n if (method_exists($e, 'getResponseBody')) {\n $body = $e->getResponseBody();\n if (is_string($body)) {\n $body = json_decode($body, true) ?? [];\n }\n $policyName = $body['policyName'] ?? $body['policy'] ?? null;\n\n // Map policy names to retry delays\n if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {\n return 10;\n }\n if ($policyName === 'SECONDLY' || $policyName === 'secondly') {\n return 1;\n }\n }\n\n // Also check nested context object if present\n if (method_exists($e, 'getResponseBody')) {\n $body = $e->getResponseBody();\n if (is_string($body)) {\n $body = json_decode($body, true) ?? [];\n }\n $context = $body['context'] ?? [];\n $policyName = $context['policyName'] ?? null;\n\n if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {\n return 10;\n }\n if ($policyName === 'SECONDLY' || $policyName === 'secondly') {\n return 1;\n }\n }\n\n $this->log->debug('[Hubspot] No retry-after header or policy name found, using default', [\n 'exception_class' => get_class($e),\n ]);\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * Execute a search request against HubSpot CRM objects with rate limiting.\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts', 'calls')\n * @param array<string, mixed> $payload The search payload with filters, sorts, properties, etc.\n * @return array The search response with 'results', 'total', 'paging' keys\n * @throws RateLimitException When rate limit is hit\n * @throws HubspotException On API errors\n */\n public function search(string $objectType, array $payload): array\n {\n $endpoint = self::BASE_URL . \"/crm/v3/objects/{$objectType}/search\";\n\n return $this->executeRequest(function () use ($endpoint, $payload) {\n $response = $this->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n });\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.3849734,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.39361703,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.40458778,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.41323137,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.421875,"top":0.09896249,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9087375101361107975
|
5225837878612723812
|
click
|
accessibility
|
NULL
|
It's the only usage in Project Files
Find Opti It's the only usage in Project Files
Find Options… (⌃⌥⌘N)
text/html
text/html
text/html
text/html
text/html
Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
69
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
// First try to get Retry-After from response headers
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
// For search APIs, headers are often missing - check response body for policyName
if (method_exists($e, 'getResponseBody')) {
$body = $e->getResponseBody();
if (is_string($body)) {
$body = json_decode($body, true) ?? [];
}
$policyName = $body['policyName'] ?? $body['policy'] ?? null;
// Map policy names to retry delays
if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {
return 10;
}
if ($policyName === 'SECONDLY' || $policyName === 'secondly') {
return 1;
}
}
// Also check nested context object if present
if (method_exists($e, 'getResponseBody')) {
$body = $e->getResponseBody();
if (is_string($body)) {
$body = json_decode($body, true) ?? [];
}
$context = $body['context'] ?? [];
$policyName = $context['policyName'] ?? null;
if ($policyName === 'TEN_SECONDLY_ROLLING' || $policyName === 'ten_secondly_rolling') {
return 10;
}
if ($policyName === 'SECONDLY' || $policyName === 'secondly') {
return 1;
}
}
$this->log->debug('[Hubspot] No retry-after header or policy name found, using default', [
'exception_class' => get_class($e),
]);
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* Execute a search request against HubSpot CRM objects with rate limiting.
*
* @param string $objectType The object type ('deals', 'companies', 'contacts', 'calls')
* @param array<string, mixed> $payload The search payload with filters, sorts, properties, etc.
* @return array The search response with 'results', 'total', 'paging' keys
* @throws RateLimitException When rate limit is hit
* @throws HubspotException On API errors
*/
public function search(string $objectType, array $payload): array
{
$endpoint = self::BASE_URL . "/crm/v3/objects/{$objectType}/search";
return $this->executeRequest(function () use ($endpoint, $payload) {
$response = $this->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
});
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
19445
|
830
|
21
|
2026-05-11T12:51:25.403236+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778503885403_m1.jpg...
|
Firefox
|
Pipelines - jiminny/app — Work
|
True
|
app.circleci.com/pipelines/github/jiminny/app
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
New Tab
New Tab
Jy 20820 es reindex stream model h New Tab
New Tab
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Close bookmarks (⌘B)
Bookmarks
Bookmarks
Close sidebar
Search bookmarks
Go to home page
Auto theme
Open notifications
Open support menu
Open user menu
org avatar Current organization: jiminny
Home
Home
Pipelines
Pipelines
Projects
Projects
Deploys
Deploys
Insights
Insights
Runners
Runners
Org
Org
Plan
Plan
Chunk sidecars
Chunk sidecars
PREVIEW
Chunk
Chunk
Dashboard All Pipelines
All Pipelines
Project Outline app
app
app
app
Overview
Overview
Settings
Settings
Deploys
Deploys
Lightning Manage triggers
Manage triggers
Trigger Pipeline
Pipelines All pipelines my-pipelines-filter...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"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.18715277,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.21006945,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.23333333,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.25659722,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close bookmarks (⌘B)","depth":6,"bounds":{"left":0.27986112,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Bookmarks","depth":5,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bookmarks","depth":6,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Search bookmarks","depth":7,"on_screen":true,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Go to home page","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Auto theme","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open notifications","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Open support menu","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Open user menu","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"org avatar Current organization: jiminny","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Home","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Home","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pipelines","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Projects","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Projects","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deploys","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deploys","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Runners","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Runners","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Org","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Org","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Plan","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Plan","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chunk sidecars","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Chunk sidecars","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PREVIEW","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chunk","depth":10,"bounds":{"left":0.5708333,"top":0.0,"width":0.06111111,"height":0.064444445},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Chunk","depth":12,"bounds":{"left":0.5868056,"top":0.0,"width":0.029166667,"height":0.019444445},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboard All Pipelines","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All Pipelines","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Outline app","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"app","depth":13,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deploys","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deploys","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Lightning Manage triggers","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Manage triggers","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Trigger Pipeline","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pipelines All pipelines my-pipelines-filter","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9087326056384412723
|
-2912693701577240446
|
idle
|
accessibility
|
NULL
|
New Tab
New Tab
Jy 20820 es reindex stream model h New Tab
New Tab
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Close bookmarks (⌘B)
Bookmarks
Bookmarks
Close sidebar
Search bookmarks
Go to home page
Auto theme
Open notifications
Open support menu
Open user menu
org avatar Current organization: jiminny
Home
Home
Pipelines
Pipelines
Projects
Projects
Deploys
Deploys
Insights
Insights
Runners
Runners
Org
Org
Plan
Plan
Chunk sidecars
Chunk sidecars
PREVIEW
Chunk
Chunk
Dashboard All Pipelines
All Pipelines
Project Outline app
app
app
app
Overview
Overview
Settings
Settings
Deploys
Deploys
Lightning Manage triggers
Manage triggers
Trigger Pipeline
Pipelines All pipelines my-pipelines-filter...
|
19443
|
NULL
|
NULL
|
NULL
|
|
25411
|
1067
|
43
|
2026-05-12T11:18:06.776490+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778584686776_m2.jpg...
|
Firefox
|
[JY-20773] User Pilot not receiving events on repo [JY-20773] User Pilot not receiving events on report generated - Jira — Work...
|
True
|
jiminny.atlassian.net/browse/JY-20773
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Unnamed Group
TypeError: League\Flysystem\Filesyst Unnamed Group
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
CloudWatch | us-east-2
CloudWatch | us-east-2
Pipelines - jiminny/app
Pipelines - jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
Platform Team - Backlog - Jira
Platform Team - Backlog - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
Close tab
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
More spaces
More spaces
Filters
Filters
More actions for Filters
More actions for Filters
Dashboards
Dashboards
Create dashboard
Create dashboard
More actions for Dashboards
More actions for Dashboards
Operations
Operations
More actions for Operations
More actions for Operations
Confluence , (opens new window)
Confluence
, (opens new window)
Teams , (opens new window)
Teams
, (opens new window)
open menu
open menu
Customise sidebar
Customise sidebar
Resize side navigation panel
Spaces
Spaces
/
Jiminny (New) Jiminny (New)
Jiminny (New)
/
Epic - Change parent
JY-19240
JY-19240
/
Bug - Change work type
JY-20773
JY-20773
Copy link
User Pilot not receiving events on report generated- Summary, edit
User Pilot not receiving events on report generated
User Pilot not receiving events on report generated
Add or create work related to this Bug
Add or create work related to this Bug
View app actions
View app actions
Collapse Key details Key details
Collapse Key details
Collapse Key details
Key details
Description
Description
Edit Description, edit
When new report is generated User Pilot should receive tracking event. The event is still in pending meaning no new event has arrived.
Steps to reproduce
Steps to reproduce
More information about
Edit Steps to reproduce, edit
None
Actual outcome
More information about
Edit Actual outcome
Add text
Expected outcome
More information about
Edit Expected outcome
Add text
Subtasks
Subtasks
Add subtask
Add subtask
Linked work items
Linked work items
Add linked work item
Add linked work item
Collapse Activity Activity
Collapse Activity
Collapse Activity
Activity
All
All
Comments
Comments
History
History
Work log
Work log
Atlassian Intelligence Summarise
Summarise
Newest first Newest first
Newest first
Add a comment…
Suggest a reply...
Suggest a reply...
Status update...
Status update...
Thanks...
Thanks...
Pro tip:
press
M
to comment
More information about Lukas Kovalik
More information about Lukas Kovalik
Lukas Kovalik
Copy link to comment
4 hours ago
The issue is most probably AutomatedReportGenerated event and not listener sending data to UP. The PR should address it.
Reply
Add thumbs up reaction
Add reaction
Edit
More actions
Resize work item view side panel
Watch options: You are watching this issue, 1 person watching
1
Share
Share
Actions
Actions
Backlog - Change status
Backlog
Automation
Automation
Improve Bug
Improve Bug
Details
Details
Details
Assignee
Assignee Pin to top. Only you can see pinned fields.
Lukas Kovalik- edit Assignee
More information about Lukas Kovalik
Lukas Kovalik
Reporter
Reporter Pin to top. Only you can see pinned fields.
Lukas Kovalik- edit Reporter
More information about Lukas Kovalik
Lukas Kovalik
Development
Development Pin to top. Only you can see pinned fields.
Open with VS Code Link to external website in new tab
Open with VS Code
1 branch
1
branch
Open branch
Create new branch
1 commit 14 days ago
1
commit
14 days ago
Open commit
Create new commit
1 pull request OPEN
1
pull request
OPEN
Open pull request
Create new pull request
Labels
Labels Pin to top. Only you can see pinned fields.
Edit Labels
None
Sub-Product
Sub-Product Pin to top. Only you can see pinned fields.
Edit Sub-Product, Add options selected, edit
Add options
Story Points
More information about
Story Points Pin to top. Only you can see pinned fields.
Edit Story Points
2
Organisations
More information about Organisations
Organisations Pin to top. Only you can see pinned fields.
Edit Organisations, None selected, edit
None
Components
Components Pin to top. Only you can see pinned fields.
Edit Components, edit
Platform
Platform
Fix versions
Fix versions Pin to top. Only you can see pinned fields.
Edit Fix versions, None selected, edit
None
Parent
More information about
Parent Pin to top. Only you can see pinned fields.
Edit Parent
Click to visit JY-19240 AJ Reports
JY-19240 AJ Reports
Sprint
More information about
Sprint Pin to top. Only you can see pinned fields.
Edit Sprint
Platform Sprint 4 Q2
Platform Sprint 4 Q2
Priority
Priority Pin to top. Only you can see pinned fields.
Edit Priority
Medium...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Unnamed Group","depth":4,"bounds":{"left":0.0028257978,"top":0.057063047,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXRadioButton","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":4,"bounds":{"left":0.0028257978,"top":0.08060654,"width":0.07679521,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":5,"bounds":{"left":0.015957447,"top":0.09217877,"width":0.40492022,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0028257978,"top":0.11332801,"width":0.07679521,"height":0.032721467},"on_screen":true,"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.015957447,"top":0.12490024,"width":0.04138963,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.14604948,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.15762171,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":4,"bounds":{"left":0.0,"top":0.17877094,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.19034317,"width":0.16140293,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.21149242,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.22306465,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":4,"bounds":{"left":0.0,"top":0.2442139,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.25578612,"width":0.1200133,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.27693537,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.28850758,"width":0.1931516,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20776] Automated report - sentry - Jira","depth":4,"bounds":{"left":0.0,"top":0.30965683,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20776] Automated report - sentry - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.32122904,"width":0.07646277,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3423783,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.35395053,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.0,"top":0.37509975,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.386672,"width":0.09524601,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Platform Team - Backlog - Jira","depth":4,"bounds":{"left":0.0,"top":0.40782124,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Team - Backlog - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.41939345,"width":0.053025264,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":4,"bounds":{"left":0.0,"top":0.4405427,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.4521149,"width":0.1200133,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.44772545,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.47326416,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.4848364,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.50758183,"width":0.07413564,"height":0.025538707},"on_screen":true,"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.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"bounds":{"left":0.090259306,"top":0.07861133,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"bounds":{"left":0.090259306,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"bounds":{"left":0.090259306,"top":0.097765364,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"bounds":{"left":0.090259306,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"bounds":{"left":0.090259306,"top":0.11691939,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"bounds":{"left":0.090259306,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"bounds":{"left":0.090259306,"top":0.13607343,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"bounds":{"left":0.08361037,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"bounds":{"left":0.0887633,"top":0.06344773,"width":0.039727394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"bounds":{"left":0.095578454,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"bounds":{"left":0.10073138,"top":0.06344773,"width":0.044215426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"bounds":{"left":0.10887633,"top":0.057861134,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"bounds":{"left":0.20694813,"top":0.06264964,"width":0.13829787,"height":0.015961692},"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.35355717,"top":0.057861134,"width":0.030086435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"bounds":{"left":0.3648604,"top":0.06384677,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"bounds":{"left":0.41206783,"top":0.057861134,"width":0.036070477,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"bounds":{"left":0.42337102,"top":0.06384677,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"bounds":{"left":0.44946808,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"bounds":{"left":0.45462102,"top":0.06344773,"width":0.027759308,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"bounds":{"left":0.46143618,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"bounds":{"left":0.4665891,"top":0.06344773,"width":0.010139627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"bounds":{"left":0.47340426,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.47855717,"top":0.06344773,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.48537233,"top":0.057861134,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"bounds":{"left":0.49052528,"top":0.06344773,"width":0.05867686,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"bounds":{"left":0.08361037,"top":0.09976058,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"bounds":{"left":0.09424867,"top":0.10574621,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"bounds":{"left":0.08361037,"top":0.12529927,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recent","depth":15,"bounds":{"left":0.09424867,"top":0.13128492,"width":0.015458777,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"bounds":{"left":0.08361037,"top":0.15083799,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Starred","depth":15,"bounds":{"left":0.09424867,"top":0.15682362,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"bounds":{"left":0.08361037,"top":0.1763767,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Apps","depth":15,"bounds":{"left":0.09424867,"top":0.18236233,"width":0.011635638,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"bounds":{"left":0.15309176,"top":0.17956904,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"bounds":{"left":0.08361037,"top":0.2019154,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"bounds":{"left":0.09424867,"top":0.20790103,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"bounds":{"left":0.13646941,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"bounds":{"left":0.14577793,"top":0.20510775,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"bounds":{"left":0.08959442,"top":0.23423783,"width":0.013464096,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"bounds":{"left":0.08759973,"top":0.2529928,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"bounds":{"left":0.09823803,"top":0.25897846,"width":0.032081116,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"bounds":{"left":0.08892952,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXMenuButton","text":"Create board","depth":18,"bounds":{"left":0.13646941,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"bounds":{"left":0.14577793,"top":0.25618514,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Team","depth":19,"bounds":{"left":0.09158909,"top":0.27853152,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Team","depth":22,"bounds":{"left":0.1022274,"top":0.28451717,"width":0.032247342,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.15309176,"top":0.28172386,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Capture Team","depth":19,"bounds":{"left":0.09158909,"top":0.30407023,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Capture Team","depth":22,"bounds":{"left":0.1022274,"top":0.31005585,"width":0.03125,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.15309176,"top":0.30726257,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Enterprise Stability Issues 🤕","depth":19,"bounds":{"left":0.09158909,"top":0.32960895,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enterprise Stability Issues 🤕","depth":22,"bounds":{"left":0.1022274,"top":0.33559456,"width":0.050531916,"height":0.030726258},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.15309176,"top":0.33280128,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Processing Team","depth":19,"bounds":{"left":0.09158909,"top":0.35514766,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Processing Team","depth":22,"bounds":{"left":0.1022274,"top":0.36113328,"width":0.038231384,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.15309176,"top":0.35834,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SE Kanban","depth":19,"bounds":{"left":0.09158909,"top":0.38068634,"width":0.06349734,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SE Kanban","depth":22,"bounds":{"left":0.1022274,"top":0.386672,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"bounds":{"left":0.15309176,"top":0.38387868,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"bounds":{"left":0.08759973,"top":0.40622506,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Service-Desk","depth":20,"bounds":{"left":0.09823803,"top":0.4122107,"width":0.03025266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"bounds":{"left":0.15442154,"top":0.4094174,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More spaces","depth":17,"bounds":{"left":0.08759973,"top":0.43176377,"width":0.0674867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More spaces","depth":20,"bounds":{"left":0.09823803,"top":0.43774942,"width":0.028756648,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":12,"bounds":{"left":0.08361037,"top":0.45730248,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Filters","depth":15,"bounds":{"left":0.09424867,"top":0.4632881,"width":0.013796543,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Filters","depth":13,"bounds":{"left":0.15309176,"top":0.46049482,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Filters","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dashboards","depth":12,"bounds":{"left":0.08361037,"top":0.4828412,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dashboards","depth":15,"bounds":{"left":0.09424867,"top":0.4888268,"width":0.026761968,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create dashboard","depth":13,"bounds":{"left":0.15508644,"top":0.48603353,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create dashboard","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Dashboards","depth":13,"bounds":{"left":0.16240026,"top":0.48603353,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Dashboards","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Operations","depth":12,"bounds":{"left":0.08361037,"top":0.5083799,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Operations","depth":15,"bounds":{"left":0.09424867,"top":0.5143655,"width":0.02443484,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Operations","depth":13,"bounds":{"left":0.15309176,"top":0.51157224,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Operations","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Confluence , (opens new window)","depth":13,"bounds":{"left":0.08361037,"top":0.5434956,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Confluence","depth":17,"bounds":{"left":0.09424867,"top":0.5494813,"width":0.025764627,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", (opens new window)","depth":15,"bounds":{"left":0.08361037,"top":0.55706304,"width":0.04837101,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Teams , (opens new window)","depth":13,"bounds":{"left":0.08361037,"top":0.56903434,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Teams","depth":17,"bounds":{"left":0.09424867,"top":0.57501996,"width":0.014793883,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", (opens new window)","depth":15,"bounds":{"left":0.08361037,"top":0.5826017,"width":0.04837101,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"open menu","depth":14,"bounds":{"left":0.14378324,"top":0.57222664,"width":0.0039893617,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"open menu","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Customise sidebar","depth":12,"bounds":{"left":0.08361037,"top":0.60415006,"width":0.071476065,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customise sidebar","depth":15,"bounds":{"left":0.09424867,"top":0.6101357,"width":0.04155585,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize side navigation panel","depth":13,"bounds":{"left":0.2109375,"top":0.0981644,"width":0.062333778,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Spaces","depth":15,"bounds":{"left":0.17137633,"top":0.10933759,"width":0.013962766,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Spaces","depth":17,"bounds":{"left":0.17137633,"top":0.11292897,"width":0.013962766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":15,"bounds":{"left":0.18716756,"top":0.11173184,"width":0.0016622341,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New) Jiminny (New)","depth":15,"bounds":{"left":0.19265293,"top":0.10933759,"width":0.034574468,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":17,"bounds":{"left":0.19996676,"top":0.11292897,"width":0.027260639,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":15,"bounds":{"left":0.22905585,"top":0.11173184,"width":0.0016622341,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Epic - Change parent","depth":15,"bounds":{"left":0.23254654,"top":0.10933759,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"JY-19240","depth":15,"bounds":{"left":0.24052526,"top":0.10933759,"width":0.017952127,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-19240","depth":17,"bounds":{"left":0.24052526,"top":0.11292897,"width":0.017952127,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":15,"bounds":{"left":0.26030585,"top":0.11173184,"width":0.0016622341,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Bug - Change work type","depth":15,"bounds":{"left":0.26379654,"top":0.10933759,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"JY-20773","depth":15,"bounds":{"left":0.27177528,"top":0.10933759,"width":0.018284574,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20773","depth":17,"bounds":{"left":0.27177528,"top":0.11292897,"width":0.018284574,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy link","depth":16,"bounds":{"left":0.28873006,"top":0.11213089,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"User Pilot not receiving events on report generated- Summary, edit","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"User Pilot not receiving events on report generated","depth":11,"bounds":{"left":0.17204122,"top":0.1396648,"width":0.19049202,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Pilot not receiving events on report generated","depth":12,"bounds":{"left":0.17204122,"top":0.13926576,"width":0.19049202,"height":0.023543496},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Add or create work related to this Bug","depth":12,"bounds":{"left":0.17137633,"top":0.17158818,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add or create work related to this Bug","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"View app actions","depth":12,"bounds":{"left":0.1846742,"top":0.17158818,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"View app actions","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Collapse Key details Key details","depth":11,"bounds":{"left":0.16339761,"top":0.20989625,"width":0.22057846,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse Key details","depth":13,"bounds":{"left":0.16206782,"top":0.21308859,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse Key details","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Key details","depth":14,"bounds":{"left":0.17137633,"top":0.2150838,"width":0.02825798,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Description","depth":12,"bounds":{"left":0.17137633,"top":0.2386273,"width":0.025598405,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Description","depth":13,"bounds":{"left":0.17137633,"top":0.23902634,"width":0.025598405,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit Description, edit","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"When new report is generated User Pilot should receive tracking event. The event is still in pending meaning no new event has arrived.","depth":14,"bounds":{"left":0.17204122,"top":0.26097366,"width":0.20113032,"height":0.03312051},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Steps to reproduce","depth":12,"bounds":{"left":0.17137633,"top":0.31723863,"width":0.042386968,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Steps to reproduce","depth":13,"bounds":{"left":0.17137633,"top":0.3180367,"width":0.042386968,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More information about","depth":12,"bounds":{"left":0.21509309,"top":0.31923383,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit Steps to reproduce, edit","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"None","depth":13,"bounds":{"left":0.17137633,"top":0.34118116,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actual outcome","depth":13,"bounds":{"left":0.17137633,"top":0.3858739,"width":0.034906916,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More information about","depth":12,"bounds":{"left":0.21027261,"top":0.386672,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit Actual outcome","depth":13,"bounds":{"left":0.25648272,"top":0.3926576,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add text","depth":14,"bounds":{"left":0.25648272,"top":0.3858739,"width":0.018450798,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Expected outcome","depth":13,"bounds":{"left":0.17137633,"top":0.42418197,"width":0.04155585,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More information about","depth":12,"bounds":{"left":0.21692154,"top":0.42498004,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit Expected outcome","depth":13,"bounds":{"left":0.25648272,"top":0.4309657,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add text","depth":14,"bounds":{"left":0.25648272,"top":0.42418197,"width":0.018450798,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Subtasks","depth":11,"bounds":{"left":0.17137633,"top":0.47765362,"width":0.023936171,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Subtasks","depth":12,"bounds":{"left":0.17137633,"top":0.47765362,"width":0.023936171,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add subtask","depth":12,"bounds":{"left":0.16738696,"top":0.49840382,"width":0.035405584,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add subtask","depth":14,"bounds":{"left":0.17137633,"top":0.5039904,"width":0.027426861,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Linked work items","depth":11,"bounds":{"left":0.17137633,"top":0.54309654,"width":0.04654255,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Linked work items","depth":12,"bounds":{"left":0.17137633,"top":0.54309654,"width":0.04654255,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add linked work item","depth":12,"bounds":{"left":0.16738696,"top":0.5622506,"width":0.05418883,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add linked work item","depth":14,"bounds":{"left":0.17137633,"top":0.5678372,"width":0.046210106,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Collapse Activity Activity","depth":12,"bounds":{"left":0.16339761,"top":0.6069433,"width":0.22057846,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse Activity","depth":14,"bounds":{"left":0.16206782,"top":0.6101357,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse Activity","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity","depth":15,"bounds":{"left":0.17137633,"top":0.6117318,"width":0.019946808,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All","depth":14,"bounds":{"left":0.17237367,"top":0.6380686,"width":0.01412899,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All","depth":16,"bounds":{"left":0.17669548,"top":0.641261,"width":0.005485372,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Comments","depth":14,"bounds":{"left":0.18716756,"top":0.6380686,"width":0.032413565,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Comments","depth":16,"bounds":{"left":0.19148937,"top":0.641261,"width":0.023769947,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"History","depth":14,"bounds":{"left":0.22024602,"top":0.6380686,"width":0.024268618,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"History","depth":16,"bounds":{"left":0.22456782,"top":0.641261,"width":0.015625,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Work log","depth":14,"bounds":{"left":0.24517952,"top":0.6380686,"width":0.02825798,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Work log","depth":16,"bounds":{"left":0.24950133,"top":0.641261,"width":0.019614361,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Atlassian Intelligence Summarise","depth":14,"bounds":{"left":0.36535904,"top":0.6420591,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarise","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Newest first Newest first","depth":13,"bounds":{"left":0.37599733,"top":0.6420591,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Newest first","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add a comment…","depth":15,"bounds":{"left":0.1853391,"top":0.68196326,"width":0.19797207,"height":0.07182761},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Suggest a reply...","depth":17,"bounds":{"left":0.19132313,"top":0.72027135,"width":0.046708778,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Suggest a reply...","depth":19,"bounds":{"left":0.1953125,"top":0.7226656,"width":0.03873005,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Status update...","depth":17,"bounds":{"left":0.2393617,"top":0.72027135,"width":0.04305186,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status update...","depth":19,"bounds":{"left":0.24335106,"top":0.7226656,"width":0.03507314,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Thanks...","depth":17,"bounds":{"left":0.28374335,"top":0.72027135,"width":0.028590426,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Thanks...","depth":19,"bounds":{"left":0.28773272,"top":0.7226656,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pro tip:","depth":16,"bounds":{"left":0.1846742,"top":0.7621708,"width":0.013796543,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"press","depth":15,"bounds":{"left":0.19847074,"top":0.7621708,"width":0.012632979,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"M","depth":17,"bounds":{"left":0.21243352,"top":0.7629689,"width":0.0034906915,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to comment","depth":15,"bounds":{"left":0.21725398,"top":0.7621708,"width":0.023603724,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"More information about Lukas Kovalik","depth":18,"bounds":{"left":0.18999335,"top":0.8036712,"width":0.031083776,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More information about Lukas Kovalik","depth":20,"bounds":{"left":0.18999335,"top":0.8032721,"width":0.031083776,"height":0.019553073},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":21,"bounds":{"left":0.18999335,"top":0.8076616,"width":0.031083776,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy link to comment","depth":18,"bounds":{"left":0.22240691,"top":0.8064645,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"4 hours ago","depth":18,"bounds":{"left":0.18999335,"top":0.82322425,"width":0.022606382,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"The issue is most probably AutomatedReportGenerated event and not listener sending data to UP. The PR should address it.","depth":19,"bounds":{"left":0.18999335,"top":0.8475658,"width":0.18999335,"height":0.03312051},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reply","depth":17,"bounds":{"left":0.18999335,"top":0.8930567,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Add thumbs up reaction","depth":17,"bounds":{"left":0.20063165,"top":0.8930567,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Add reaction","depth":17,"bounds":{"left":0.21126994,"top":0.8930567,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":17,"bounds":{"left":0.22190824,"top":0.8930567,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"More actions","depth":17,"bounds":{"left":0.23254654,"top":0.8930567,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Resize work item view side panel","depth":12,"bounds":{"left":0.7077792,"top":0.0981644,"width":0.07280585,"height":0.01396648},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Watch options: You are watching this issue, 1 person watching","depth":13,"bounds":{"left":0.44830453,"top":0.10694334,"width":0.017121011,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":17,"bounds":{"left":0.45960772,"top":0.11292897,"width":0.0018284575,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Share","depth":14,"bounds":{"left":0.4680851,"top":0.10694334,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Share","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Actions","depth":14,"bounds":{"left":0.48138297,"top":0.10694334,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Actions","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Backlog - Change status","depth":11,"bounds":{"left":0.39860374,"top":0.14365523,"width":0.03174867,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Backlog","depth":13,"bounds":{"left":0.40259308,"top":0.14964086,"width":0.017785905,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Automation","depth":11,"bounds":{"left":0.43567154,"top":0.14365523,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Automation","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Improve Bug","depth":11,"bounds":{"left":0.39860374,"top":0.17877094,"width":0.042220745,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Improve Bug","depth":13,"bounds":{"left":0.40791222,"top":0.18475658,"width":0.028922873,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Details","depth":14,"bounds":{"left":0.40159574,"top":0.22266561,"width":0.08211436,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXHeading","text":"Details","depth":17,"bounds":{"left":0.41090426,"top":0.22585794,"width":0.01861702,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Details","depth":18,"bounds":{"left":0.41090426,"top":0.22625698,"width":0.017287234,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.40525267,"top":0.26296887,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Assignee Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.42852393,"top":0.26376694,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Lukas Kovalik- edit Assignee","depth":12,"bounds":{"left":0.40525267,"top":0.29289705,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"More information about Lukas Kovalik","depth":13,"bounds":{"left":0.40525267,"top":0.28371906,"width":0.04055851,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.41589096,"top":0.28651237,"width":0.029920213,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporter","depth":12,"bounds":{"left":0.40525267,"top":0.3196329,"width":0.019281914,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Reporter Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.42719415,"top":0.3200319,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Lukas Kovalik- edit Reporter","depth":12,"bounds":{"left":0.40525267,"top":0.34956107,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"More information about Lukas Kovalik","depth":13,"bounds":{"left":0.40525267,"top":0.34038308,"width":0.04055851,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.41589096,"top":0.34277734,"width":0.029920213,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Development","depth":12,"bounds":{"left":0.40525267,"top":0.3790902,"width":0.029421542,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Development Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.43733376,"top":0.37869114,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Open with VS Code Link to external website in new tab","depth":12,"bounds":{"left":0.40259308,"top":0.39984038,"width":0.082446806,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open with VS Code","depth":15,"bounds":{"left":0.4112367,"top":0.40582603,"width":0.043218084,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 branch","depth":13,"bounds":{"left":0.40259308,"top":0.4253791,"width":0.082446806,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":16,"bounds":{"left":0.40591756,"top":0.43136472,"width":0.0019946808,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"branch","depth":16,"bounds":{"left":0.40791222,"top":0.43136472,"width":0.01662234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Open branch","depth":13,"bounds":{"left":0.46974733,"top":0.4253791,"width":0.007978723,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Create new branch","depth":13,"bounds":{"left":0.47839096,"top":0.4253791,"width":0.0066489363,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"1 commit 14 days ago","depth":13,"bounds":{"left":0.40259308,"top":0.4509178,"width":0.082446806,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":16,"bounds":{"left":0.40591756,"top":0.45690343,"width":0.0019946808,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commit","depth":16,"bounds":{"left":0.40791222,"top":0.45690343,"width":0.017453458,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14 days ago","depth":17,"bounds":{"left":0.45994017,"top":0.4577015,"width":0.02244016,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Open commit","depth":13,"bounds":{"left":0.46841756,"top":0.4509178,"width":0.007978723,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Create new commit","depth":13,"bounds":{"left":0.47706118,"top":0.4509178,"width":0.007978723,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"1 pull request OPEN","depth":13,"bounds":{"left":0.40259308,"top":0.4764565,"width":0.082446806,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":16,"bounds":{"left":0.40591756,"top":0.48244214,"width":0.0019946808,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"pull request","depth":16,"bounds":{"left":0.40791222,"top":0.48244214,"width":0.027094414,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OPEN","depth":18,"bounds":{"left":0.47057846,"top":0.4848364,"width":0.010472074,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Open pull request","depth":13,"bounds":{"left":0.46841756,"top":0.4764565,"width":0.007978723,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Create new pull request","depth":13,"bounds":{"left":0.47706118,"top":0.4764565,"width":0.007978723,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.40525267,"top":0.5151636,"width":0.01462766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Labels Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.4225399,"top":0.5159617,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Labels","depth":12,"bounds":{"left":0.40525267,"top":0.5450918,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"None","depth":13,"bounds":{"left":0.40525267,"top":0.5387071,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sub-Product","depth":12,"bounds":{"left":0.40525267,"top":0.5718276,"width":0.02825798,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Sub-Product Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.43617022,"top":0.57222664,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Sub-Product, Add options selected, edit","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add options","depth":12,"bounds":{"left":0.40525267,"top":0.5949721,"width":0.02642952,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Story Points","depth":12,"bounds":{"left":0.40525267,"top":0.6280926,"width":0.026928192,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More information about","depth":11,"bounds":{"left":0.43617022,"top":0.62849164,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Story Points Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.44414893,"top":0.62849164,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Story Points","depth":12,"bounds":{"left":0.40525267,"top":0.65802073,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":15,"bounds":{"left":0.40874335,"top":0.6532322,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Organisations","depth":12,"bounds":{"left":0.40525267,"top":0.6843575,"width":0.030751329,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More information about Organisations","depth":11,"bounds":{"left":0.43999335,"top":0.68595374,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Organisations Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.4479721,"top":0.68515563,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Organisations, None selected, edit","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"None","depth":12,"bounds":{"left":0.40525267,"top":0.70790106,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Components","depth":12,"bounds":{"left":0.40525267,"top":0.7410216,"width":0.028424202,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Components Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.43633643,"top":0.74142057,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Components, edit","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Platform","depth":12,"bounds":{"left":0.4069149,"top":0.76256984,"width":0.018450798,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform","depth":13,"bounds":{"left":0.4069149,"top":0.7649641,"width":0.018450798,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix versions","depth":12,"bounds":{"left":0.40525267,"top":0.7972865,"width":0.026595745,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Fix versions Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.43450797,"top":0.79768556,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Fix versions, None selected, edit","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"None","depth":12,"bounds":{"left":0.40525267,"top":0.82083,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parent","depth":12,"bounds":{"left":0.40525267,"top":0.85355145,"width":0.014461436,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More information about","depth":11,"bounds":{"left":0.42370346,"top":0.85434955,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Parent Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.43168217,"top":0.85434955,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Parent","depth":12,"bounds":{"left":0.40525267,"top":0.88347965,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Click to visit JY-19240 AJ Reports","depth":13,"bounds":{"left":0.41323137,"top":0.8758978,"width":0.04920213,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-19240 AJ Reports","depth":14,"bounds":{"left":0.41456118,"top":0.877095,"width":0.04654255,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sprint","depth":12,"bounds":{"left":0.40525267,"top":0.9102155,"width":0.013297873,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More information about","depth":11,"bounds":{"left":0.4225399,"top":0.91061455,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Sprint Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.43051863,"top":0.91061455,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Sprint","depth":12,"bounds":{"left":0.40525267,"top":0.94014364,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Platform Sprint 4 Q2","depth":13,"bounds":{"left":0.40525267,"top":0.9333599,"width":0.044714097,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2","depth":14,"bounds":{"left":0.40525267,"top":0.9333599,"width":0.044714097,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Priority","depth":12,"bounds":{"left":0.40525267,"top":0.96648043,"width":0.016123671,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Priority Pin to top. Only you can see pinned fields.","depth":11,"bounds":{"left":0.4240359,"top":0.9668795,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit Priority","depth":12,"bounds":{"left":0.40525267,"top":0.99640864,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Medium","depth":13,"bounds":{"left":0.41323137,"top":0.990024,"width":0.017785905,"height":0.009976029},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9087317327699081296
|
6070239912495511684
|
visual_change
|
accessibility
|
NULL
|
Unnamed Group
TypeError: League\Flysystem\Filesyst Unnamed Group
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
CloudWatch | us-east-2
CloudWatch | us-east-2
Pipelines - jiminny/app
Pipelines - jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking for automated report generated by LakyLak · Pull Request #12024 · jiminny/app
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
Platform Team - Backlog - Jira
Platform Team - Backlog - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
Close tab
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Sidebar
Sidebar
Top Bar
Top Bar
Main Content
Main Content
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
More spaces
More spaces
Filters
Filters
More actions for Filters
More actions for Filters
Dashboards
Dashboards
Create dashboard
Create dashboard
More actions for Dashboards
More actions for Dashboards
Operations
Operations
More actions for Operations
More actions for Operations
Confluence , (opens new window)
Confluence
, (opens new window)
Teams , (opens new window)
Teams
, (opens new window)
open menu
open menu
Customise sidebar
Customise sidebar
Resize side navigation panel
Spaces
Spaces
/
Jiminny (New) Jiminny (New)
Jiminny (New)
/
Epic - Change parent
JY-19240
JY-19240
/
Bug - Change work type
JY-20773
JY-20773
Copy link
User Pilot not receiving events on report generated- Summary, edit
User Pilot not receiving events on report generated
User Pilot not receiving events on report generated
Add or create work related to this Bug
Add or create work related to this Bug
View app actions
View app actions
Collapse Key details Key details
Collapse Key details
Collapse Key details
Key details
Description
Description
Edit Description, edit
When new report is generated User Pilot should receive tracking event. The event is still in pending meaning no new event has arrived.
Steps to reproduce
Steps to reproduce
More information about
Edit Steps to reproduce, edit
None
Actual outcome
More information about
Edit Actual outcome
Add text
Expected outcome
More information about
Edit Expected outcome
Add text
Subtasks
Subtasks
Add subtask
Add subtask
Linked work items
Linked work items
Add linked work item
Add linked work item
Collapse Activity Activity
Collapse Activity
Collapse Activity
Activity
All
All
Comments
Comments
History
History
Work log
Work log
Atlassian Intelligence Summarise
Summarise
Newest first Newest first
Newest first
Add a comment…
Suggest a reply...
Suggest a reply...
Status update...
Status update...
Thanks...
Thanks...
Pro tip:
press
M
to comment
More information about Lukas Kovalik
More information about Lukas Kovalik
Lukas Kovalik
Copy link to comment
4 hours ago
The issue is most probably AutomatedReportGenerated event and not listener sending data to UP. The PR should address it.
Reply
Add thumbs up reaction
Add reaction
Edit
More actions
Resize work item view side panel
Watch options: You are watching this issue, 1 person watching
1
Share
Share
Actions
Actions
Backlog - Change status
Backlog
Automation
Automation
Improve Bug
Improve Bug
Details
Details
Details
Assignee
Assignee Pin to top. Only you can see pinned fields.
Lukas Kovalik- edit Assignee
More information about Lukas Kovalik
Lukas Kovalik
Reporter
Reporter Pin to top. Only you can see pinned fields.
Lukas Kovalik- edit Reporter
More information about Lukas Kovalik
Lukas Kovalik
Development
Development Pin to top. Only you can see pinned fields.
Open with VS Code Link to external website in new tab
Open with VS Code
1 branch
1
branch
Open branch
Create new branch
1 commit 14 days ago
1
commit
14 days ago
Open commit
Create new commit
1 pull request OPEN
1
pull request
OPEN
Open pull request
Create new pull request
Labels
Labels Pin to top. Only you can see pinned fields.
Edit Labels
None
Sub-Product
Sub-Product Pin to top. Only you can see pinned fields.
Edit Sub-Product, Add options selected, edit
Add options
Story Points
More information about
Story Points Pin to top. Only you can see pinned fields.
Edit Story Points
2
Organisations
More information about Organisations
Organisations Pin to top. Only you can see pinned fields.
Edit Organisations, None selected, edit
None
Components
Components Pin to top. Only you can see pinned fields.
Edit Components, edit
Platform
Platform
Fix versions
Fix versions Pin to top. Only you can see pinned fields.
Edit Fix versions, None selected, edit
None
Parent
More information about
Parent Pin to top. Only you can see pinned fields.
Edit Parent
Click to visit JY-19240 AJ Reports
JY-19240 AJ Reports
Sprint
More information about
Sprint Pin to top. Only you can see pinned fields.
Edit Sprint
Platform Sprint 4 Q2
Platform Sprint 4 Q2
Priority
Priority Pin to top. Only you can see pinned fields.
Edit Priority
Medium...
|
25409
|
NULL
|
NULL
|
NULL
|
|
18208
|
791
|
9
|
2026-05-11T11:04:09.273594+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778497449273_m2.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
VIewWindowmelp°9 JY-20725-handle-HS-search-rate-li VIewWindowmelp°9 JY-20725-handle-HS-search-rate-linProiect(C) TranscodeParameterRescl© UserService.php© Uuid.php> D Traits> D UseCases> D User> D Utils› D Validation> OvOphp nelpers.ong© InitialFrontendState.php© Jiminny.phpc) Plan.oho© Serializer.phpC) TeamScimDetails.ohpbootstrap>C build> contia>@ contrib→ database>M docsM front-end>D lang> node_modules library rootM ohostan> M nublic>O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.onopnp customer_api.onppnp embedded.ongphp nealtn.onppnp scim.onophp uprotectedweb.phpphp web.phpphp webhook.php>O scriptsv O storage•aoo>M debugbar… M frameworkv Mloas.aitianoreê audio. wav= custom.loalC) Hubspot/Service.onp(C) HubSoot/Service.pnpo RematchActivityonCrmObiectDetach.pngC) CheckAnсRateLimitException.phc(C) CrmobiectsResolver.pho() ProviderRateLimiter.phpclass Cuient extends BasecLient imolen352369377= hubspot-journal-poll.log= laravel log< nhnunit ymus tht isorivate function createBatchconfia'inputClass' => \HubSpit @1ssetSconfiqurationsSoInval1dArqumentorivate function orenareßatchReaue$batchReadRequest = $batchConfSinnutClacs = ChatchtonfiortirSinputs = array_map(function (Sinput = new SinputClassSinput->setId($crmId):return $input;}. ScrmIds):SbatchReadRequest->setInputs($SbatchReadReguest->setPropertiorivate function validateAoiResoonif @ Sresponse)4throw new_CrmExcentiondmnnivate function nroceccAniReculto• SearchYour team is now on the Free plan with 1 admin. You retain editing access and other members are read-only. View team permissions to see who can edit, or upgrade to restore collaborationV COLLECTIONSs9: An error occurrea› CRM Owners> CRM Pipelines› Dealsengagements>D OLD ENGAGEMENTSGet list meetingsrosl search tasksGET read callGeT list callsPOST meetings scheduledGET det meetinorost det link to task>POST Create Contact with Association› Hubspotv teration run HSGET Read copyeg. An error occurred.se. successful operationv teration run Search HSrost search contact oy emall copy> Journal & webhoooks v4› OAuth› Properties• DECCADOLSEARCHPOSt search contact by phonePOST search contact by emailPOST search meetingsPOST search notesPost Search callc vaPOST Search related meetinas v3PoSt coarch deals> Ticketsv UlcofullPOST search dealsPOST Read a batch of obiecPost Read a batch of assorGET Readteration run Search HS (#8)u Iteration run Search HS • 20 VUs • May 11, 2026 13:16:51 (1 min) • Fixed profileSummaryTotal requests sent ©Requests/second ©Avg. response time ©P90 ©6.563109,40157 ms176 ms% 10012-16•5412-17•0012-17-0612-17-1212•17-18Dorformonso dotolle fortotol durotinnPOST search contact by email Copy6.563107.21> POST filter per comoanv / onlv oven deal stagesGet engagements old associated by dealSustem Resource WarningSustem resources are constrained. Thesystem may not be able to generate the loadeded for this test and the cest is likely to- Connect Git = Concole 5.) TerminaGET Read Copyhl• Preparation tor kerl.. In oo m100% Lz• Mon 11 May 14:04:080 Iteration run Search HSPOSt search contact by emaiD Iteration run Search HSNo environmenP95 O203 msP99 ©401 msError % ©0,00Failure % ©0,00Peak CPU % ©Peak Memory % ©999 %19.2 %Filter bv requestsvAva. response390 ms 140 req/s3000.0012-17-24Failure %0.0012-17-20112-17-26|12-17•4212•17•49- Requests/second - Ava. response - Error % — Virtual users ..• CPU % •.• Memory %Resp. time (Ava. ms)Min (ms)Max ms)203401Globals Vault Tools?000...
|
NULL
|
-9087051478434250741
|
NULL
|
visual_change
|
ocr
|
NULL
|
VIewWindowmelp°9 JY-20725-handle-HS-search-rate-li VIewWindowmelp°9 JY-20725-handle-HS-search-rate-linProiect(C) TranscodeParameterRescl© UserService.php© Uuid.php> D Traits> D UseCases> D User> D Utils› D Validation> OvOphp nelpers.ong© InitialFrontendState.php© Jiminny.phpc) Plan.oho© Serializer.phpC) TeamScimDetails.ohpbootstrap>C build> contia>@ contrib→ database>M docsM front-end>D lang> node_modules library rootM ohostan> M nublic>O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.onopnp customer_api.onppnp embedded.ongphp nealtn.onppnp scim.onophp uprotectedweb.phpphp web.phpphp webhook.php>O scriptsv O storage•aoo>M debugbar… M frameworkv Mloas.aitianoreê audio. wav= custom.loalC) Hubspot/Service.onp(C) HubSoot/Service.pnpo RematchActivityonCrmObiectDetach.pngC) CheckAnсRateLimitException.phc(C) CrmobiectsResolver.pho() ProviderRateLimiter.phpclass Cuient extends BasecLient imolen352369377= hubspot-journal-poll.log= laravel log< nhnunit ymus tht isorivate function createBatchconfia'inputClass' => \HubSpit @1ssetSconfiqurationsSoInval1dArqumentorivate function orenareßatchReaue$batchReadRequest = $batchConfSinnutClacs = ChatchtonfiortirSinputs = array_map(function (Sinput = new SinputClassSinput->setId($crmId):return $input;}. ScrmIds):SbatchReadRequest->setInputs($SbatchReadReguest->setPropertiorivate function validateAoiResoonif @ Sresponse)4throw new_CrmExcentiondmnnivate function nroceccAniReculto• SearchYour team is now on the Free plan with 1 admin. You retain editing access and other members are read-only. View team permissions to see who can edit, or upgrade to restore collaborationV COLLECTIONSs9: An error occurrea› CRM Owners> CRM Pipelines› Dealsengagements>D OLD ENGAGEMENTSGet list meetingsrosl search tasksGET read callGeT list callsPOST meetings scheduledGET det meetinorost det link to task>POST Create Contact with Association› Hubspotv teration run HSGET Read copyeg. An error occurred.se. successful operationv teration run Search HSrost search contact oy emall copy> Journal & webhoooks v4› OAuth› Properties• DECCADOLSEARCHPOSt search contact by phonePOST search contact by emailPOST search meetingsPOST search notesPost Search callc vaPOST Search related meetinas v3PoSt coarch deals> Ticketsv UlcofullPOST search dealsPOST Read a batch of obiecPost Read a batch of assorGET Readteration run Search HS (#8)u Iteration run Search HS • 20 VUs • May 11, 2026 13:16:51 (1 min) • Fixed profileSummaryTotal requests sent ©Requests/second ©Avg. response time ©P90 ©6.563109,40157 ms176 ms% 10012-16•5412-17•0012-17-0612-17-1212•17-18Dorformonso dotolle fortotol durotinnPOST search contact by email Copy6.563107.21> POST filter per comoanv / onlv oven deal stagesGet engagements old associated by dealSustem Resource WarningSustem resources are constrained. Thesystem may not be able to generate the loadeded for this test and the cest is likely to- Connect Git = Concole 5.) TerminaGET Read Copyhl• Preparation tor kerl.. In oo m100% Lz• Mon 11 May 14:04:080 Iteration run Search HSPOSt search contact by emaiD Iteration run Search HSNo environmenP95 O203 msP99 ©401 msError % ©0,00Failure % ©0,00Peak CPU % ©Peak Memory % ©999 %19.2 %Filter bv requestsvAva. response390 ms 140 req/s3000.0012-17-24Failure %0.0012-17-20112-17-26|12-17•4212•17•49- Requests/second - Ava. response - Error % — Virtual users ..• CPU % •.• Memory %Resp. time (Ava. ms)Min (ms)Max ms)203401Globals Vault Tools?000...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
20287
|
873
|
18
|
2026-05-11T14:52:47.736165+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778511167736_m2.jpg...
|
Code
|
Client.php (Working Tree) (Client.php) — app — 9 p Client.php (Working Tree) (Client.php) — app — 9 problems in this file • Modified...
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 17 pending changes
17
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Testing
Claude Code
SOURCE CONTROL
SOURCE CONTROL
Changes Section
CHANGES
CHANGES
Commit Changes on "JY-20725-handle-HS-search-rate-limit"
Commit
More Actions...
Changes
17
.env.local
M
.env.nikilocal
U
.env.other
U
ids.txt
U
raw_sql_query.sql
U
WEBHOOK_FILTERING_IMPLEMENTATION.md
U
JiminnyDebugCommand.php
app/Console/Commands
M
SimulateWebhooksCommand.php
app/Console/Commands/Crm/Hubspot
U
CreateMockAskJiminnyReportResultCommand.php
app/Console/Commands/Reports
U
RateLimitException.php
app/Exceptions
M
MatchActivityCrmData.php
app/Jobs/Crm
M
Client.php
app/Services/Crm/Hubspot
9, M
logging.php
config
M
favicon.ico
public
U
HandleHubspotRateLimitTest.php
tests/Unit/Jobs/Middleware
M
CanAccessAiReportsTest.php
tests/Unit/Policies
U
ClientTest.php
tests/Unit/Services/Crm/Hubspot
M
Graph Section
GRAPH
GRAPH
JY-20725 add more tests
Lukas Kovalik
JY-20725-handle-HS-search-rate-limit
JY-20725 add tests
Lukas Kovalik
JY-20725 add HS rate limit handling on activities rematching
Lukas Kovalik
Merge pull request #12056 from jiminny/JY-20818-move-AJ-reports-to-separated-datadog-metric
Lukas Kovalik
origin/master
Merge branch 'master' into JY-20818-move-AJ-reports-to-separated-datadog-metric
Lukas Kovalik
Merge pull request #12057 from jiminny/JY-20819-increase-download-transctip-rate-limit
mihailmihaylovjiminny
JY-20819: Increase download transcription rate limit
mihail.mihaylov
JY-20818 move ask jiminny reports to its own datadog metric
Lukas Kovalik
Merge pull request #12052 from jiminny/JY-20817-fix-deleting-old-tracks
mihailmihaylovjiminny
Merge branch 'master' into JY-20817-fix-deleting-old-tracks
mihailmihaylovjiminny
Merge pull request #12047 from jiminny/JY-20662-remove-word-boost
ilian-jiminny
JY-20662 return void
ilian
JY-20662 Removed word_boost parameter from Assembly transcription request
ilian
JY-20817: Fix deleting old tracks
mihail.mihaylov
Merge pull request #12043 from jiminny/JY-19938-bot-status-in-csv-es
ilian-jiminny
Merge branch 'master' into JY-19938-bot-status-in-csv-es
ilian-jiminny
Merge pull request #12044 from jiminny/JY-19938-ES-mapping-update
ilian-jiminny
JY-19938 Added consent information and recording error reason to Elastic Search mapping
ilian
JY-19938 reorder array map
ilian
JY-19938: Address PR review comments
ilian
JY-19938 lint fixes
ilian
HandleHubspotRateLimitTest.php (Working Tree) (HandleHubspotRateLimitTest.php), Editor Group 1
ClientTest.php (Working Tree) (ClientTest.php), Editor Group 1
Client.php (Working Tree) (Client.php), Editor Group 1
MatchActivityCrmData.php (Working Tree) (MatchActivityCrmData.php), Editor Group 1
RateLimitException.php (Working Tree) (RateLimitException.php), Editor Group 1
Review rate limit handli…, Editor Group 2
remote
app (Git) - JY-20725-handle-HS-search-rate-limit*, Checkout Branch/Tag...
JY-20725-handle-HS-search-rate-limit*
app (Git) - Synchronize Changes
Errors: 6, Warnings: 11, Infos: 28
6
11
28
Notifications
key, PHP extension: Premium features not active.
8.3, Language Level: 8.3
Sign In
Sign In
PHP
LF
UTF-8
Spaces: 4
Ln 120, Col 1
git-commit Not Committed Yet
Not Committed Yet
Diff editor
Clear
Review rate limit handling for HubSpot job queue
Session history
New session
Message actions
RateLimitException.php#9-9
RateLimitException.php#9-9
Reveiw the diff. Mostly
@app/Jobs/Crm/MatchActivityCrmData.php
,
@app/Exceptions/RateLimitException.php
,
@app/Jobs/Middleware/HandleHubspotRateLimit.php
,
@app/Services/Crm/Hubspot/Client.php
and
@app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php
. The issue is I am trying to make sure that instant spike of MatchActivityCrmData jobs willl handle 429 exceptions from hubspot. Revewi ti carefully and try to see potential issues and bottlenecks. Also RateLimitException was changerd from LogicException to RuntimeException. Is it ok. This exception is used by other paerts of code. Will ti break anything?
Thought for 5s
Thought for 5s
I'll review the implementation carefully. Let me first check how
RateLimitException
is used elsewhere and look at the test files and
PaginationState
.
Bash
Find all usages of RateLimitException outside the changed files
IN
grep -rn "RateLimitException" /Users/lukas/jiminny/app/app --include="*.php" | grep -v "HandleHubspotRateLimit\|MatchActivityCrmData\|Client.php\|RateLimitException.php"
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:13:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception
/Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php:17:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php:68: RateLimitException |
/Users/lukas/jiminny/app/app/Component/TranscriptionSummary/Jobs/SummarizeTranscriptionJob.php:15:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/TranscriptionSummary/Jobs/SummarizeTranscriptionJob.php:58: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception
/Users/lukas/jiminny/app/app/Component/AiActivityType/Jobs/GenerateAiActivityTypeJob.php:19:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/AiActivityType/Jobs/GenerateAiActivityTypeJob.php:76: RateLimitException |
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/HubspotClientInterface.php:8:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/HubspotClientInterface.php:50: * @throws RateLimitException When rate limit is hit
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:195: // RateLimitException and other exceptions are re-thrown as-is
Read
PaginationState.php
PaginationState.php
Read
HandleHubspotRateLimitTest.php
HandleHubspotRateLimitTest.php
Bash
Check how RateLimitException is used in GenerateActionItemsJob
IN
grep -rn "RateLimitException\|LogicException\|RuntimeException" /Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php | head -20
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:13:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception
Bash
Find all catch blocks or instanceof checks for RateLimitException
IN
grep -rn "catch.*RateLimitException\|instanceof RateLimitException" /Users/lukas/jiminny/app/app --include="*.php"
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/app/Jobs/Middleware/HandleHubspotRateLimit.php:11: * Job middleware that catches RateLimitException from HubSpot API calls
/Users/lukas/jiminny/app/app/Jobs/Middleware/HandleHubspotRateLimit.php:24: } catch (RateLimitException $e) {
/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:149: if (! $e instanceof RateLimitException) {
Bash
Find all test references to RateLimitException
IN
grep -rn "RateLimitException" /Users/lukas/jiminny/app/tests --include="*.php"
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:8:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:13:#[CoversClass(RateLimitException::class)]
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:14:class RateLimitExceptionTest extends TestCase
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:18: $exception = new RateLimitException();
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:28: $exception = new RateLimitException('Hubspot rate limit', 30, $previous);
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:52: $exception = new RateLimitException('test', $input);
/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:10:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:49: public function testPropagatesNonRateLimitExceptions(): void
/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:103: throw new RateLimitException('rate limited', $retryAfter);
/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:150: throw new RateLimitException('rate limited', 1);
Bash
Check retry/failure handling in GenerateActionItemsJob
IN
grep -n "RateLimitException\|retryUntil\|backoff\|maxExceptions\|maxTries\|release\|failed" /Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php | head -30
Copy code to clipboard
OUT
13:use Jiminny\Exceptions\RateLimitException;
51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception
56: $this->release(30);
Bash
Check retry/failure handling in GenerateAiCallScoringJob
IN
grep -n "RateLimitException\|retryUntil\|backoff\|maxExceptions\|maxTries\|release\|failed" /Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php | head -30
Copy code to clipboard
OUT
17:use Jiminny\Exceptions\RateLimitException;
68: RateLimitException |
75: $this->release(30);
Bash
Check retry config in MatchActivityCrmData
IN
grep -n "retryAfter\|RETRY_WINDOW\|retryUntil\|maxTries" /Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php
Copy code to clipboard
OUT
34: private const int RETRY_WINDOW_MINUTES = 30;
45: public function retryUntil(): \DateTimeInterface
47: return now()->addMinutes(self::RETRY_WINDOW_MINUTES);
77: return self::RETRY_WINDOW_MINUTES * 60 + 60;
Bash
Check the cache key format
IN
grep -n "getRateLimitCacheKey\|hubspot:ratelimit" /Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Client.php
Copy code to clipboard
OUT
78: $cacheKey = $this->getRateLimitCacheKey();
110: private function getRateLimitCacheKey(): string
112: return sprintf('hubspot:ratelimit:portal:%d', $this->config->getId());
Bash
Find other jobs that might use the rate limit middleware
IN
grep -rn "class.*Middleware\|HandleHubspotRateLimit" /Users/lukas/jiminny/app/app/Jobs --include="*.php" | grep -v "HandleHubspotRateLimit.php"
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:18:use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:42: return [new HandleHubspotRateLimit()];
Read
HubspotClientInterface.php
HubspotClientInterface.php
Thought for 73s
Thought for 73s
Now I have a complete picture. Here's my full analysis:
Review Summary
Review Summary
RuntimeException vs LogicException — Safe ✓
RuntimeException
vs
LogicException
— Safe ✓
The change is semantically correct and won't break anything.
LogicException
is for programmer errors (invalid arguments, contract violations). A rate limit from an external API is a runtime condition —
RuntimeException
is the right parent. All callers catch
RateLimitException
by name explicitly (union catches in
GenerateActionItemsJob
,
GenerateAiCallScoringJob
,
SummarizeTranscriptionJob
,
GenerateAiActivityTypeJob
) or check
instanceof RateLimitException
— none relies on the parent class type, so nothing breaks.
Issue 1 — Circuit breaker stores stale delay (most important bug)
Issue 1 — Circuit breaker stores stale delay (most important bug)
Client.php:94
Client.php:94
Copy code to clipboard
Redis::setex($cacheKey, $retryAfter, (string) $retryAfter);
The TTL is
$retryAfter
seconds, but the
stored value
is also the original
$retryAfter
. If a second job reads this cache 20 seconds later, it throws
RateLimitException(retryAfter=30)
and gets delayed 30 more seconds — even though only 10 remain. In a spike of 100 jobs, each subsequent job inflates its wait.
Fix:
store the absolute expiry timestamp, reconstruct the remaining delay when reading:
Copy code to clipboard
// on 429:
Redis::setex($cacheKey, $retryAfter, (string) (time() + $retryAfter));
// in the cached-read branch:
$remaining = max(1, (int) $cachedRetryAfter - time());
throw new RateLimitException('Hubspot rate limit (cached circuit-breaker)', $remaining);
Issue 2 — retryUntil() window may expire under sustained rate limiting
Issue 2 —
retryUntil()
window may expire under sustained rate limiting
MatchActivityCrmData.php:45-47
MatchActivityCrmData.php:45-47
retryUntil()
is calculated as
now() + 30 min
at
dispatch time
and stored in the job payload. With
MAX_RETRY_DELAY = 600s
, you only get ~3 rate-limit-triggered releases before the 30-minute window closes and the job is permanently failed. For a heavy 429 spike (daily limit, parsed as 600s), this can easily happen.
Consider increasing
RETRY_WINDOW_MINUTES
to 60 or more, or making it configurable. The
uniqueFor()
value should be updated to match.
Issue 3 — Only search() uses the circuit breaker, but other methods can still hit 429
Issue 3 — Only
search()
uses the circuit breaker, but other methods can still hit 429
Client.php:76-108
Client.php:76-108
executeRequest()
is only called from
search()
. Methods like
getOpportunityById()
,
batchReadObjects()
,
getContactByEmail()
bypass it entirely. If HubSpot's 429 is account-wide (not search-endpoint-specific), those methods will keep firing even while the circuit breaker is supposedly open. This is likely fine because the search endpoint has its own tighter quota (5 RPS), but it's worth being explicit in a comment.
Issue 4 — object $job type in middleware has no compile-time safety
Issue 4 —
object $job
type in middleware has no compile-time safety
HandleHubspotRateLimit.php:20
HandleHubspotRateLimit.php:20
Copy code to clipboard
public function handle(object $job, callable $next): void
Calling
$job->attempts()
and
$job->release()
on
object
will work at runtime since Laravel always passes jobs that use
InteractsWithQueue
, but PHPStan/psalm won't verify this and it could silently break in tests with bare mocks (as your test does use a
Job
mock that has
attempts()
— so the test is fine, but the real type contract is invisible). Minor, but worth tightening to
\Illuminate\Contracts\Queue\Job
.
What works well ✓
What works well ✓
RateLimitException
is caught by the middleware...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Explorer (⇧⌘E)","depth":19,"bounds":{"left":0.0,"top":0.047885075,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.057462092,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Search (⇧⌘F)","depth":19,"bounds":{"left":0.0,"top":0.08619314,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.09577015,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Source Control (⌃⇧G) - 17 pending changes","depth":19,"bounds":{"left":0.0,"top":0.1245012,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":true},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.13407822,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"17","depth":22,"bounds":{"left":0.00831117,"top":0.1452514,"width":0.003656915,"height":0.008778931},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.008643617,"top":0.14604948,"width":0.0016622341,"height":0.007980846}},{"char_start":1,"char_count":1,"bounds":{"left":0.009973404,"top":0.14604948,"width":0.0019946808,"height":0.007980846}}],"role_description":"text"},{"role":"AXRadioButton","text":"Run and Debug (⇧⌘D)","depth":19,"bounds":{"left":0.0,"top":0.16280925,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.17238627,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Remote Explorer","depth":19,"bounds":{"left":0.0,"top":0.20111732,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.21069433,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Extensions (⇧⌘X) - 2 require update","depth":19,"bounds":{"left":0.0,"top":0.23942538,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.2490024,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":22,"bounds":{"left":0.009640957,"top":0.2601756,"width":0.0019946808,"height":0.008778931},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Testing","depth":19,"bounds":{"left":0.0,"top":0.27773345,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.28731045,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Claude Code","depth":19,"bounds":{"left":0.0,"top":0.3160415,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"SOURCE CONTROL","depth":17,"bounds":{"left":0.022606382,"top":0.047885075,"width":0.034242023,"height":0.02793296},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"SOURCE CONTROL","depth":18,"bounds":{"left":0.022606382,"top":0.056664005,"width":0.034242023,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Changes Section","depth":21,"bounds":{"left":0.015957447,"top":0.07581804,"width":0.09940159,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"","depth":23,"bounds":{"left":0.01662234,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"CHANGES","depth":22,"bounds":{"left":0.022606382,"top":0.07581804,"width":0.01861702,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"CHANGES","depth":23,"bounds":{"left":0.022606382,"top":0.079010375,"width":0.01861702,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"","depth":28,"bounds":{"left":0.024601065,"top":0.09896249,"width":0.07247341,"height":0.015961692},"on_screen":true,"value":"","role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Commit Changes on \"JY-20725-handle-HS-search-rate-limit\"","depth":26,"bounds":{"left":0.022273935,"top":0.1245012,"width":0.08045213,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.052526597,"top":0.12849163,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Commit","depth":27,"bounds":{"left":0.058843084,"top":0.1292897,"width":0.014960106,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.059175532,"top":0.1292897,"width":0.0029920214,"height":0.011173184}},{"char_start":1,"char_count":5,"bounds":{"left":0.061835106,"top":0.1292897,"width":0.011968086,"height":0.011173184}}],"role_description":"text"},{"role":"AXPopUpButton","text":"More Actions...","depth":26,"bounds":{"left":0.10305851,"top":0.1245012,"width":0.00831117,"height":0.0207502},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.1043883,"top":0.12849163,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.019614361,"top":0.15163608,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Changes","depth":27,"bounds":{"left":0.025930852,"top":0.15163608,"width":0.01761968,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.15243416,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.028922873,"top":0.15243416,"width":0.014960106,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"17","depth":27,"bounds":{"left":0.10571808,"top":0.15243416,"width":0.0039893617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10605053,"top":0.15243416,"width":0.0016622341,"height":0.0103751}},{"char_start":1,"char_count":1,"bounds":{"left":0.10771277,"top":0.15243416,"width":0.0019946808,"height":0.0103751}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.16759777,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.local","depth":28,"bounds":{"left":0.028590426,"top":0.16919394,"width":0.01861702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.16999201,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.029920213,"top":0.16999201,"width":0.01761968,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.16999201,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.18515563,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.nikilocal","depth":28,"bounds":{"left":0.028590426,"top":0.1867518,"width":0.025598405,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.18754987,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.029920213,"top":0.18754987,"width":0.024268618,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.18754987,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.20271349,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.other","depth":28,"bounds":{"left":0.028590426,"top":0.20430966,"width":0.019946808,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.20510775,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.029920213,"top":0.20510775,"width":0.01861702,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.20510775,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.22027135,"width":0.0076462766,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ids.txt","depth":28,"bounds":{"left":0.028590426,"top":0.22186752,"width":0.012300532,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.22266561,"width":0.0009973404,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.029587766,"top":0.22266561,"width":0.011635638,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.22266561,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.23782921,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"raw_sql_query.sql","depth":28,"bounds":{"left":0.028590426,"top":0.23942538,"width":0.035904255,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.24022347,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":16,"bounds":{"left":0.03025266,"top":0.24022347,"width":0.034242023,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.24022347,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.25538707,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"WEBHOOK_FILTERING_IMPLEMENTATION.md","depth":28,"bounds":{"left":0.028590426,"top":0.25698325,"width":0.076130316,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.25778133,"width":0.0043218085,"height":0.011971269}},{"char_start":1,"char_count":34,"bounds":{"left":0.032912236,"top":0.25778133,"width":0.08909574,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.25778133,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.27294493,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyDebugCommand.php","depth":28,"bounds":{"left":0.028590426,"top":0.2745411,"width":0.05817819,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.2753392,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.030917553,"top":0.2753392,"width":0.055851065,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Console/Commands","depth":28,"bounds":{"left":0.08843085,"top":0.2745411,"width":0.01462766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.0887633,"top":0.27613726,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":19,"bounds":{"left":0.09075798,"top":0.27613726,"width":0.043218084,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.2753392,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.2905028,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SimulateWebhooksCommand.php","depth":28,"bounds":{"left":0.028590426,"top":0.29209897,"width":0.06781915,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.29289705,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":26,"bounds":{"left":0.03125,"top":0.29289705,"width":0.065159574,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Console/Commands/Crm/Hubspot","depth":28,"bounds":{"left":0.098071806,"top":0.29209897,"width":0.005984043,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.09840426,"top":0.29369512,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":31,"bounds":{"left":0.100398935,"top":0.29369512,"width":0.06881649,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.29289705,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.30806065,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php","depth":28,"bounds":{"left":0.028590426,"top":0.30965683,"width":0.07646277,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.3104549,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":42,"bounds":{"left":0.03158245,"top":0.3104549,"width":0.099734046,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Console/Commands/Reports","depth":28,"bounds":{"left":0.10538564,"top":0.3104549,"width":0.0003324468,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.13331117,"top":0.31125298,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":27,"bounds":{"left":0.13530585,"top":0.31125298,"width":0.05851064,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.3104549,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.3256185,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException.php","depth":28,"bounds":{"left":0.028590426,"top":0.3272147,"width":0.047539894,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.32801276,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":21,"bounds":{"left":0.03158245,"top":0.32801276,"width":0.04488032,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Exceptions","depth":28,"bounds":{"left":0.078125,"top":0.3272147,"width":0.024933511,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.078125,"top":0.32881084,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":13,"bounds":{"left":0.08045213,"top":0.32881084,"width":0.026263298,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.32801276,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.34317636,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php","depth":28,"bounds":{"left":0.028590426,"top":0.34477255,"width":0.054521278,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.34557062,"width":0.0039893617,"height":0.011971269}},{"char_start":1,"char_count":23,"bounds":{"left":0.032579787,"top":0.34557062,"width":0.050531916,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Jobs/Crm","depth":28,"bounds":{"left":0.084773935,"top":0.34477255,"width":0.020279255,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.084773935,"top":0.3463687,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":11,"bounds":{"left":0.087101065,"top":0.3463687,"width":0.023603724,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.34557062,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.36073422,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Client.php","depth":28,"bounds":{"left":0.028590426,"top":0.3623304,"width":0.020611702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.36312848,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.03158245,"top":0.36312848,"width":0.01761968,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"app/Services/Crm/Hubspot","depth":28,"bounds":{"left":0.05119681,"top":0.3623304,"width":0.028590426,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.05119681,"top":0.3639266,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":23,"bounds":{"left":0.053523935,"top":0.3639266,"width":0.047539894,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"9, M","depth":28,"bounds":{"left":0.10206117,"top":0.36312848,"width":0.00831117,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10206117,"top":0.36312848,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.10472074,"top":0.36312848,"width":0.005984043,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.3782921,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"logging.php","depth":28,"bounds":{"left":0.028590426,"top":0.37988827,"width":0.023936171,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.38068634,"width":0.0009973404,"height":0.011971269}},{"char_start":1,"char_count":10,"bounds":{"left":0.029587766,"top":0.38068634,"width":0.022938829,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"config","depth":28,"bounds":{"left":0.05418883,"top":0.38068634,"width":0.011968086,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.054521278,"top":0.38148445,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":5,"bounds":{"left":0.05651596,"top":0.38148445,"width":0.009640957,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.38068634,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.39584997,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"favicon.ico","depth":28,"bounds":{"left":0.028590426,"top":0.39744613,"width":0.021609042,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.3982442,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":10,"bounds":{"left":0.03025266,"top":0.3982442,"width":0.020279255,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"public","depth":28,"bounds":{"left":0.05219415,"top":0.3982442,"width":0.011303191,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.05219415,"top":0.3990423,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":5,"bounds":{"left":0.054521278,"top":0.3990423,"width":0.008976064,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.3982442,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.41340783,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HandleHubspotRateLimitTest.php","depth":28,"bounds":{"left":0.028590426,"top":0.415004,"width":0.06781915,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.41580206,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":29,"bounds":{"left":0.031914894,"top":0.41580206,"width":0.064494684,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"tests/Unit/Jobs/Middleware","depth":28,"bounds":{"left":0.098071806,"top":0.415004,"width":0.004986702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.098071806,"top":0.41660017,"width":0.0016622341,"height":0.011173184}},{"char_start":1,"char_count":25,"bounds":{"left":0.09940159,"top":0.41660017,"width":0.04886968,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.41580206,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.4309657,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CanAccessAiReportsTest.php","depth":28,"bounds":{"left":0.028590426,"top":0.43256184,"width":0.059175532,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.43335995,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":25,"bounds":{"left":0.03158245,"top":0.43335995,"width":0.05618351,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"tests/Unit/Policies","depth":28,"bounds":{"left":0.089428194,"top":0.43256184,"width":0.013962766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.08976064,"top":0.43415803,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":18,"bounds":{"left":0.091090426,"top":0.43415803,"width":0.031914894,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"U","depth":28,"bounds":{"left":0.107380316,"top":0.43335995,"width":0.0029920214,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":28,"bounds":{"left":0.021276595,"top":0.44852355,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ClientTest.php","depth":28,"bounds":{"left":0.028590426,"top":0.4501197,"width":0.028922873,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.4509178,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.03158245,"top":0.4509178,"width":0.026263298,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"tests/Unit/Services/Crm/Hubspot","depth":28,"bounds":{"left":0.059507977,"top":0.4501197,"width":0.043882977,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.059507977,"top":0.4517159,"width":0.0016622341,"height":0.011173184}},{"char_start":1,"char_count":30,"bounds":{"left":0.060837764,"top":0.4517159,"width":0.059507977,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"M","depth":28,"bounds":{"left":0.106715426,"top":0.4509178,"width":0.003656915,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Graph Section","depth":21,"bounds":{"left":0.015957447,"top":0.60015965,"width":0.09940159,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"","depth":23,"bounds":{"left":0.01662234,"top":0.60255384,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"GRAPH","depth":22,"bounds":{"left":0.022606382,"top":0.60015965,"width":0.013297873,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"GRAPH","depth":23,"bounds":{"left":0.022606382,"top":0.60415006,"width":0.013297873,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20725 add more tests","depth":28,"bounds":{"left":0.023271276,"top":0.6201117,"width":0.038231384,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.023271276,"top":0.6209098,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":22,"bounds":{"left":0.025930852,"top":0.6209098,"width":0.05086436,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.061835106,"top":0.6209098,"width":0.0003324468,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.078457445,"top":0.6217079,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":12,"bounds":{"left":0.080784574,"top":0.6217079,"width":0.023271276,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.06382979,"top":0.6201117,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20725-handle-HS-search-rate-limit","depth":27,"bounds":{"left":0.06948138,"top":0.6209098,"width":0.032579787,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.06948138,"top":0.6209098,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":35,"bounds":{"left":0.07180851,"top":0.6209098,"width":0.071476065,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.10571808,"top":0.6201117,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20725 add tests","depth":28,"bounds":{"left":0.023271276,"top":0.63766956,"width":0.03956117,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.023271276,"top":0.63846767,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":17,"bounds":{"left":0.025598405,"top":0.63846767,"width":0.03723404,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.064494684,"top":0.63846767,"width":0.024933511,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.06482713,"top":0.6392658,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":12,"bounds":{"left":0.066821806,"top":0.6392658,"width":0.022938829,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching","depth":28,"bounds":{"left":0.023271276,"top":0.6552275,"width":0.08577128,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.023271276,"top":0.6560255,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":59,"bounds":{"left":0.025598405,"top":0.6560255,"width":0.11968085,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.109707445,"top":0.6560255,"width":0.0003324468,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14727394,"top":0.65682364,"width":0.0023271276,"height":0.011173184}},{"char_start":1,"char_count":12,"bounds":{"left":0.14926861,"top":0.65682364,"width":0.022938829,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12056 from jiminny/JY-20818-move-AJ-reports-to-separated-datadog-metric","depth":28,"bounds":{"left":0.026928192,"top":0.67278534,"width":0.049534574,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.0774601,"top":0.6735834,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.07945479,"top":0.67278534,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"origin/master","depth":27,"bounds":{"left":0.08510638,"top":0.6735834,"width":0.024933511,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-20818-move-AJ-reports-to-separated-datadog-metric","depth":28,"bounds":{"left":0.030585106,"top":0.6903432,"width":0.078457445,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.109707445,"top":0.69114125,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12057 from jiminny/JY-20819-increase-download-transctip-rate-limit","depth":28,"bounds":{"left":0.030585106,"top":0.70790106,"width":0.078457445,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":28,"bounds":{"left":0.109707445,"top":0.7086991,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20819: Increase download transcription rate limit","depth":28,"bounds":{"left":0.030585106,"top":0.7254589,"width":0.078457445,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihail.mihaylov","depth":28,"bounds":{"left":0.109707445,"top":0.72625697,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20818 move ask jiminny reports to its own datadog metric","depth":28,"bounds":{"left":0.030585106,"top":0.7430168,"width":0.07945479,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":28,"bounds":{"left":0.109707445,"top":0.7438148,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12052 from jiminny/JY-20817-fix-deleting-old-tracks","depth":28,"bounds":{"left":0.030585106,"top":0.76057464,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":28,"bounds":{"left":0.109707445,"top":0.7613727,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-20817-fix-deleting-old-tracks","depth":28,"bounds":{"left":0.030585106,"top":0.7781325,"width":0.078125,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":28,"bounds":{"left":0.109707445,"top":0.77893054,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12047 from jiminny/JY-20662-remove-word-boost","depth":28,"bounds":{"left":0.030585106,"top":0.79569036,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian-jiminny","depth":28,"bounds":{"left":0.109707445,"top":0.7964884,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20662 return void","depth":28,"bounds":{"left":0.030585106,"top":0.8132482,"width":0.043218084,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.075465426,"top":0.81404626,"width":0.0076462766,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20662 Removed word_boost parameter from Assembly transcription request","depth":28,"bounds":{"left":0.030585106,"top":0.8308061,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.109707445,"top":0.8316041,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20817: Fix deleting old tracks","depth":28,"bounds":{"left":0.030585106,"top":0.84836394,"width":0.06582447,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mihail.mihaylov","depth":28,"bounds":{"left":0.098071806,"top":0.84836394,"width":0.010305851,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12043 from jiminny/JY-19938-bot-status-in-csv-es","depth":28,"bounds":{"left":0.030585106,"top":0.8659218,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian-jiminny","depth":28,"bounds":{"left":0.109707445,"top":0.8667199,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-19938-bot-status-in-csv-es","depth":28,"bounds":{"left":0.030585106,"top":0.88347965,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian-jiminny","depth":28,"bounds":{"left":0.109707445,"top":0.88427776,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Merge pull request #12044 from jiminny/JY-19938-ES-mapping-update","depth":28,"bounds":{"left":0.030585106,"top":0.9010375,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian-jiminny","depth":28,"bounds":{"left":0.109707445,"top":0.9018356,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-19938 Added consent information and recording error reason to Elastic Search mapping","depth":28,"bounds":{"left":0.030585106,"top":0.9185954,"width":0.0787899,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.109707445,"top":0.9193935,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-19938 reorder array map","depth":28,"bounds":{"left":0.030585106,"top":0.93615323,"width":0.056848403,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.089428194,"top":0.93695134,"width":0.00731383,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-19938: Address PR review comments","depth":28,"bounds":{"left":0.030585106,"top":0.9537111,"width":0.07912234,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.109707445,"top":0.9545092,"width":0.0003324468,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-19938 lint fixes","depth":28,"bounds":{"left":0.030585106,"top":0.97126895,"width":0.03756649,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ilian","depth":28,"bounds":{"left":0.06981383,"top":0.97206706,"width":0.0076462766,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"HandleHubspotRateLimitTest.php (Working Tree) (HandleHubspotRateLimitTest.php), Editor Group 1","depth":28,"on_screen":false,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ClientTest.php (Working Tree) (ClientTest.php), Editor Group 1","depth":28,"bounds":{"left":0.11569149,"top":0.047885075,"width":0.08577128,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Client.php (Working Tree) (Client.php), Editor Group 1","depth":28,"bounds":{"left":0.20113032,"top":0.047885075,"width":0.08211436,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"MatchActivityCrmData.php (Working Tree) (MatchActivityCrmData.php), Editor Group 1","depth":28,"bounds":{"left":0.28324467,"top":0.047885075,"width":0.11103723,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"RateLimitException.php (Working Tree) (RateLimitException.php), Editor Group 1","depth":28,"bounds":{"left":0.39394948,"top":0.047885075,"width":0.09075798,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.12832446,"top":0.07821229,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.15093085,"top":0.07821229,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.16489361,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.1875,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.22074468,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.22606383,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.24401596,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.24933511,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Review rate limit handli…, Editor Group 2","depth":28,"bounds":{"left":0.5578458,"top":0.047885075,"width":0.07014628,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXButton","text":"remote","depth":16,"bounds":{"left":0.0006648936,"top":0.98244214,"width":0.010638298,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"app (Git) - JY-20725-handle-HS-search-rate-limit*, Checkout Branch/Tag...","depth":16,"bounds":{"left":0.012965426,"top":0.98244214,"width":0.084773935,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.013962766,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JY-20725-handle-HS-search-rate-limit*","depth":17,"bounds":{"left":0.019281914,"top":0.9856345,"width":0.0774601,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"app (Git) - Synchronize Changes","depth":16,"bounds":{"left":0.09740692,"top":0.98244214,"width":0.0076462766,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Errors: 6, Warnings: 11, Infos: 28","depth":16,"bounds":{"left":0.107380316,"top":0.98244214,"width":0.03756649,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.109042555,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":17,"bounds":{"left":0.1143617,"top":0.9856345,"width":0.004986702,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.11934841,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"11","depth":17,"bounds":{"left":0.124667555,"top":0.9856345,"width":0.00731383,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.13164894,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"28","depth":17,"bounds":{"left":0.13696809,"top":0.9856345,"width":0.0063164895,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Notifications","depth":16,"bounds":{"left":0.9886968,"top":0.98244214,"width":0.010638298,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"key, PHP extension: Premium features not active.","depth":16,"bounds":{"left":0.9790558,"top":0.98244214,"width":0.008643617,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"8.3, Language Level: 8.3","depth":16,"bounds":{"left":0.9674202,"top":0.98244214,"width":0.009640957,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sign In","depth":16,"bounds":{"left":0.9428192,"top":0.98244214,"width":0.022938829,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.9444814,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sign In","depth":17,"bounds":{"left":0.94980055,"top":0.9856345,"width":0.014295213,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"PHP","depth":16,"bounds":{"left":0.92952126,"top":0.98244214,"width":0.011635638,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"LF","depth":16,"bounds":{"left":0.91988033,"top":0.98244214,"width":0.007978723,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"UTF-8","depth":16,"bounds":{"left":0.90226066,"top":0.98244214,"width":0.015625,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Spaces: 4","depth":16,"bounds":{"left":0.87832445,"top":0.98244214,"width":0.022273935,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ln 120, Col 1","depth":16,"bounds":{"left":0.84773934,"top":0.98244214,"width":0.028922873,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"git-commit Not Committed Yet","depth":16,"bounds":{"left":0.80019945,"top":0.98244214,"width":0.045545213,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.8018617,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Not Committed Yet","depth":17,"bounds":{"left":0.8071808,"top":0.9856345,"width":0.036901597,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Diff editor","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Clear","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Review rate limit handling for HubSpot job queue","depth":19,"bounds":{"left":0.56017286,"top":0.08060654,"width":0.099734046,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Session history","depth":19,"bounds":{"left":0.9780585,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"Session history","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New session","depth":19,"bounds":{"left":0.9886968,"top":0.08060654,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"New session","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Message actions","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RateLimitException.php#9-9","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"RateLimitException.php#9-9","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Reveiw the diff. Mostly","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Jobs/Crm/MatchActivityCrmData.php","depth":26,"on_screen":false,"help_text":"Open app/Jobs/Crm/MatchActivityCrmData.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Exceptions/RateLimitException.php","depth":26,"on_screen":false,"help_text":"Open app/Exceptions/RateLimitException.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Jobs/Middleware/HandleHubspotRateLimit.php","depth":26,"on_screen":false,"help_text":"Open app/Jobs/Middleware/HandleHubspotRateLimit.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":",","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Services/Crm/Hubspot/Client.php","depth":26,"on_screen":false,"help_text":"Open app/Services/Crm/Hubspot/Client.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"and","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"@app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php","depth":26,"on_screen":false,"help_text":"Open app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":". The issue is I am trying to make sure that instant spike of MatchActivityCrmData jobs willl handle 429 exceptions from hubspot. Revewi ti carefully and try to see potential issues and bottlenecks. Also RateLimitException was changerd from LogicException to RuntimeException. Is it ok. This exception is used by other paerts of code. Will ti break anything?","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thought for 5s","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thought for 5s","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"I'll review the implementation carefully. Let me first check how","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is used elsewhere and look at the test files and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PaginationState","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Find all usages of RateLimitException outside the changed files","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -rn \"RateLimitException\" /Users/lukas/jiminny/app/app --include=\"*.php\" | grep -v \"HandleHubspotRateLimit\\|MatchActivityCrmData\\|Client.php\\|RateLimitException.php\"","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:13:use Jiminny\\Exceptions\\RateLimitException;\n/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception\n/Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php:17:use Jiminny\\Exceptions\\RateLimitException;\n/Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php:68: RateLimitException |\n/Users/lukas/jiminny/app/app/Component/TranscriptionSummary/Jobs/SummarizeTranscriptionJob.php:15:use Jiminny\\Exceptions\\RateLimitException;\n/Users/lukas/jiminny/app/app/Component/TranscriptionSummary/Jobs/SummarizeTranscriptionJob.php:58: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception\n/Users/lukas/jiminny/app/app/Component/AiActivityType/Jobs/GenerateAiActivityTypeJob.php:19:use Jiminny\\Exceptions\\RateLimitException;\n/Users/lukas/jiminny/app/app/Component/AiActivityType/Jobs/GenerateAiActivityTypeJob.php:76: RateLimitException |\n/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/HubspotClientInterface.php:8:use Jiminny\\Exceptions\\RateLimitException;\n/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/HubspotClientInterface.php:50: * @throws RateLimitException When rate limit is hit\n/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:195: // RateLimitException and other exceptions are re-thrown as-is","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"PaginationState.php","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PaginationState.php","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"HandleHubspotRateLimitTest.php","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"HandleHubspotRateLimitTest.php","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check how RateLimitException is used in GenerateActionItemsJob","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -rn \"RateLimitException\\|LogicException\\|RuntimeException\" /Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php | head -20","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:13:use Jiminny\\Exceptions\\RateLimitException;\n/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Find all catch blocks or instanceof checks for RateLimitException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -rn \"catch.*RateLimitException\\|instanceof RateLimitException\" /Users/lukas/jiminny/app/app --include=\"*.php\"","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Middleware/HandleHubspotRateLimit.php:11: * Job middleware that catches RateLimitException from HubSpot API calls\n/Users/lukas/jiminny/app/app/Jobs/Middleware/HandleHubspotRateLimit.php:24: } catch (RateLimitException $e) {\n/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:149: if (! $e instanceof RateLimitException) {","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Find all test references to RateLimitException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -rn \"RateLimitException\" /Users/lukas/jiminny/app/tests --include=\"*.php\"","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:8:use Jiminny\\Exceptions\\RateLimitException;\n/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:13:#[CoversClass(RateLimitException::class)]\n/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:14:class RateLimitExceptionTest extends TestCase\n/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:18: $exception = new RateLimitException();\n/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:28: $exception = new RateLimitException('Hubspot rate limit', 30, $previous);\n/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:52: $exception = new RateLimitException('test', $input);\n/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:10:use Jiminny\\Exceptions\\RateLimitException;\n/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:49: public function testPropagatesNonRateLimitExceptions(): void\n/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:103: throw new RateLimitException('rate limited', $retryAfter);\n/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:150: throw new RateLimitException('rate limited', 1);","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check retry/failure handling in GenerateActionItemsJob","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -n \"RateLimitException\\|retryUntil\\|backoff\\|maxExceptions\\|maxTries\\|release\\|failed\" /Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php | head -30","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"13:use Jiminny\\Exceptions\\RateLimitException;\n51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception\n56: $this->release(30);","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check retry/failure handling in GenerateAiCallScoringJob","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -n \"RateLimitException\\|retryUntil\\|backoff\\|maxExceptions\\|maxTries\\|release\\|failed\" /Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php | head -30","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"17:use Jiminny\\Exceptions\\RateLimitException;\n68: RateLimitException |\n75: $this->release(30);","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check retry config in MatchActivityCrmData","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -n \"retryAfter\\|RETRY_WINDOW\\|retryUntil\\|maxTries\" /Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"34: private const int RETRY_WINDOW_MINUTES = 30;\n45: public function retryUntil(): \\DateTimeInterface\n47: return now()->addMinutes(self::RETRY_WINDOW_MINUTES);\n77: return self::RETRY_WINDOW_MINUTES * 60 + 60;","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Check the cache key format","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -n \"getRateLimitCacheKey\\|hubspot:ratelimit\" /Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Client.php","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"78: $cacheKey = $this->getRateLimitCacheKey();\n110: private function getRateLimitCacheKey(): string\n112: return sprintf('hubspot:ratelimit:portal:%d', $this->config->getId());","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Find other jobs that might use the rate limit middleware","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -rn \"class.*Middleware\\|HandleHubspotRateLimit\" /Users/lukas/jiminny/app/app/Jobs --include=\"*.php\" | grep -v \"HandleHubspotRateLimit.php\"","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:18:use Jiminny\\Jobs\\Middleware\\HandleHubspotRateLimit;\n/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:42: return [new HandleHubspotRateLimit()];","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"HubspotClientInterface.php","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"HubspotClientInterface.php","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thought for 73s","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thought for 73s","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now I have a complete picture. Here's my full analysis:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Review Summary","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Review Summary","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"RuntimeException vs LogicException — Safe ✓","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"RuntimeException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"vs","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogicException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— Safe ✓","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The change is semantically correct and won't break anything.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogicException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is for programmer errors (invalid arguments, contract violations). A rate limit from an external API is a runtime condition —","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RuntimeException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is the right parent. All callers catch","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"by name explicitly (union catches in","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateActionItemsJob","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateAiCallScoringJob","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SummarizeTranscriptionJob","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateAiActivityTypeJob","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":") or check","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"instanceof RateLimitException","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— none relies on the parent class type, so nothing breaks.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Issue 1 — Circuit breaker stores stale delay (most important bug)","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Issue 1 — Circuit breaker stores stale delay (most important bug)","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Client.php:94","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Client.php:94","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":23,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Redis::setex($cacheKey, $retryAfter, (string) $retryAfter);","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The TTL is","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$retryAfter","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"seconds, but the","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"stored value","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is also the original","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$retryAfter","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". If a second job reads this cache 20 seconds later, it throws","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException(retryAfter=30)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and gets delayed 30 more seconds — even though only 10 remain. In a spike of 100 jobs, each subsequent job inflates its wait.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fix:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"store the absolute expiry timestamp, reconstruct the remaining delay when reading:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":23,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"// on 429:\nRedis::setex($cacheKey, $retryAfter, (string) (time() + $retryAfter));\n\n// in the cached-read branch:\n$remaining = max(1, (int) $cachedRetryAfter - time());\nthrow new RateLimitException('Hubspot rate limit (cached circuit-breaker)', $remaining);","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Issue 2 — retryUntil() window may expire under sustained rate limiting","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Issue 2 —","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"retryUntil()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"window may expire under sustained rate limiting","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"MatchActivityCrmData.php:45-47","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"MatchActivityCrmData.php:45-47","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"retryUntil()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is calculated as","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"now() + 30 min","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"at","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"dispatch time","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and stored in the job payload. With","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MAX_RETRY_DELAY = 600s","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", you only get ~3 rate-limit-triggered releases before the 30-minute window closes and the job is permanently failed. For a heavy 429 spike (daily limit, parsed as 600s), this can easily happen.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Consider increasing","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RETRY_WINDOW_MINUTES","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"to 60 or more, or making it configurable. The","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"uniqueFor()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"value should be updated to match.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Issue 3 — Only search() uses the circuit breaker, but other methods can still hit 429","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Issue 3 — Only","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"search()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"uses the circuit breaker, but other methods can still hit 429","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Client.php:76-108","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Client.php:76-108","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"executeRequest()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is only called from","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"search()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". Methods like","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"getOpportunityById()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"batchReadObjects()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"getContactByEmail()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"bypass it entirely. If HubSpot's 429 is account-wide (not search-endpoint-specific), those methods will keep firing even while the circuit breaker is supposedly open. This is likely fine because the search endpoint has its own tighter quota (5 RPS), but it's worth being explicit in a comment.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Issue 4 — object $job type in middleware has no compile-time safety","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Issue 4 —","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"object $job","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"type in middleware has no compile-time safety","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"HandleHubspotRateLimit.php:20","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"HandleHubspotRateLimit.php:20","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":23,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"public function handle(object $job, callable $next): void","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calling","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$job->attempts()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$job->release()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"on","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"object","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"will work at runtime since Laravel always passes jobs that use","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"InteractsWithQueue","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", but PHPStan/psalm won't verify this and it could silently break in tests with bare mocks (as your test does use a","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Job","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"mock that has","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"attempts()","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— so the test is fine, but the real type contract is invisible). Minor, but worth tightening to","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"\\Illuminate\\Contracts\\Queue\\Job","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"What works well ✓","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"What works well ✓","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is caught by the middleware","depth":24,"on_screen":false,"role_description":"text"}]...
|
-9085806743506945806
|
6120906794114589251
|
idle
|
accessibility
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 17 pending changes
17
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Testing
Claude Code
SOURCE CONTROL
SOURCE CONTROL
Changes Section
CHANGES
CHANGES
Commit Changes on "JY-20725-handle-HS-search-rate-limit"
Commit
More Actions...
Changes
17
.env.local
M
.env.nikilocal
U
.env.other
U
ids.txt
U
raw_sql_query.sql
U
WEBHOOK_FILTERING_IMPLEMENTATION.md
U
JiminnyDebugCommand.php
app/Console/Commands
M
SimulateWebhooksCommand.php
app/Console/Commands/Crm/Hubspot
U
CreateMockAskJiminnyReportResultCommand.php
app/Console/Commands/Reports
U
RateLimitException.php
app/Exceptions
M
MatchActivityCrmData.php
app/Jobs/Crm
M
Client.php
app/Services/Crm/Hubspot
9, M
logging.php
config
M
favicon.ico
public
U
HandleHubspotRateLimitTest.php
tests/Unit/Jobs/Middleware
M
CanAccessAiReportsTest.php
tests/Unit/Policies
U
ClientTest.php
tests/Unit/Services/Crm/Hubspot
M
Graph Section
GRAPH
GRAPH
JY-20725 add more tests
Lukas Kovalik
JY-20725-handle-HS-search-rate-limit
JY-20725 add tests
Lukas Kovalik
JY-20725 add HS rate limit handling on activities rematching
Lukas Kovalik
Merge pull request #12056 from jiminny/JY-20818-move-AJ-reports-to-separated-datadog-metric
Lukas Kovalik
origin/master
Merge branch 'master' into JY-20818-move-AJ-reports-to-separated-datadog-metric
Lukas Kovalik
Merge pull request #12057 from jiminny/JY-20819-increase-download-transctip-rate-limit
mihailmihaylovjiminny
JY-20819: Increase download transcription rate limit
mihail.mihaylov
JY-20818 move ask jiminny reports to its own datadog metric
Lukas Kovalik
Merge pull request #12052 from jiminny/JY-20817-fix-deleting-old-tracks
mihailmihaylovjiminny
Merge branch 'master' into JY-20817-fix-deleting-old-tracks
mihailmihaylovjiminny
Merge pull request #12047 from jiminny/JY-20662-remove-word-boost
ilian-jiminny
JY-20662 return void
ilian
JY-20662 Removed word_boost parameter from Assembly transcription request
ilian
JY-20817: Fix deleting old tracks
mihail.mihaylov
Merge pull request #12043 from jiminny/JY-19938-bot-status-in-csv-es
ilian-jiminny
Merge branch 'master' into JY-19938-bot-status-in-csv-es
ilian-jiminny
Merge pull request #12044 from jiminny/JY-19938-ES-mapping-update
ilian-jiminny
JY-19938 Added consent information and recording error reason to Elastic Search mapping
ilian
JY-19938 reorder array map
ilian
JY-19938: Address PR review comments
ilian
JY-19938 lint fixes
ilian
HandleHubspotRateLimitTest.php (Working Tree) (HandleHubspotRateLimitTest.php), Editor Group 1
ClientTest.php (Working Tree) (ClientTest.php), Editor Group 1
Client.php (Working Tree) (Client.php), Editor Group 1
MatchActivityCrmData.php (Working Tree) (MatchActivityCrmData.php), Editor Group 1
RateLimitException.php (Working Tree) (RateLimitException.php), Editor Group 1
Review rate limit handli…, Editor Group 2
remote
app (Git) - JY-20725-handle-HS-search-rate-limit*, Checkout Branch/Tag...
JY-20725-handle-HS-search-rate-limit*
app (Git) - Synchronize Changes
Errors: 6, Warnings: 11, Infos: 28
6
11
28
Notifications
key, PHP extension: Premium features not active.
8.3, Language Level: 8.3
Sign In
Sign In
PHP
LF
UTF-8
Spaces: 4
Ln 120, Col 1
git-commit Not Committed Yet
Not Committed Yet
Diff editor
Clear
Review rate limit handling for HubSpot job queue
Session history
New session
Message actions
RateLimitException.php#9-9
RateLimitException.php#9-9
Reveiw the diff. Mostly
@app/Jobs/Crm/MatchActivityCrmData.php
,
@app/Exceptions/RateLimitException.php
,
@app/Jobs/Middleware/HandleHubspotRateLimit.php
,
@app/Services/Crm/Hubspot/Client.php
and
@app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php
. The issue is I am trying to make sure that instant spike of MatchActivityCrmData jobs willl handle 429 exceptions from hubspot. Revewi ti carefully and try to see potential issues and bottlenecks. Also RateLimitException was changerd from LogicException to RuntimeException. Is it ok. This exception is used by other paerts of code. Will ti break anything?
Thought for 5s
Thought for 5s
I'll review the implementation carefully. Let me first check how
RateLimitException
is used elsewhere and look at the test files and
PaginationState
.
Bash
Find all usages of RateLimitException outside the changed files
IN
grep -rn "RateLimitException" /Users/lukas/jiminny/app/app --include="*.php" | grep -v "HandleHubspotRateLimit\|MatchActivityCrmData\|Client.php\|RateLimitException.php"
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:13:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception
/Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php:17:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php:68: RateLimitException |
/Users/lukas/jiminny/app/app/Component/TranscriptionSummary/Jobs/SummarizeTranscriptionJob.php:15:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/TranscriptionSummary/Jobs/SummarizeTranscriptionJob.php:58: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception
/Users/lukas/jiminny/app/app/Component/AiActivityType/Jobs/GenerateAiActivityTypeJob.php:19:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/AiActivityType/Jobs/GenerateAiActivityTypeJob.php:76: RateLimitException |
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/HubspotClientInterface.php:8:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/HubspotClientInterface.php:50: * @throws RateLimitException When rate limit is hit
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:195: // RateLimitException and other exceptions are re-thrown as-is
Read
PaginationState.php
PaginationState.php
Read
HandleHubspotRateLimitTest.php
HandleHubspotRateLimitTest.php
Bash
Check how RateLimitException is used in GenerateActionItemsJob
IN
grep -rn "RateLimitException\|LogicException\|RuntimeException" /Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php | head -20
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:13:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php:51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception
Bash
Find all catch blocks or instanceof checks for RateLimitException
IN
grep -rn "catch.*RateLimitException\|instanceof RateLimitException" /Users/lukas/jiminny/app/app --include="*.php"
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/app/Jobs/Middleware/HandleHubspotRateLimit.php:11: * Job middleware that catches RateLimitException from HubSpot API calls
/Users/lukas/jiminny/app/app/Jobs/Middleware/HandleHubspotRateLimit.php:24: } catch (RateLimitException $e) {
/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:149: if (! $e instanceof RateLimitException) {
Bash
Find all test references to RateLimitException
IN
grep -rn "RateLimitException" /Users/lukas/jiminny/app/tests --include="*.php"
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:8:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:13:#[CoversClass(RateLimitException::class)]
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:14:class RateLimitExceptionTest extends TestCase
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:18: $exception = new RateLimitException();
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:28: $exception = new RateLimitException('Hubspot rate limit', 30, $previous);
/Users/lukas/jiminny/app/tests/Unit/Exceptions/RateLimitExceptionTest.php:52: $exception = new RateLimitException('test', $input);
/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:10:use Jiminny\Exceptions\RateLimitException;
/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:49: public function testPropagatesNonRateLimitExceptions(): void
/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:103: throw new RateLimitException('rate limited', $retryAfter);
/Users/lukas/jiminny/app/tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php:150: throw new RateLimitException('rate limited', 1);
Bash
Check retry/failure handling in GenerateActionItemsJob
IN
grep -n "RateLimitException\|retryUntil\|backoff\|maxExceptions\|maxTries\|release\|failed" /Users/lukas/jiminny/app/app/Component/ActionItems/Jobs/GenerateActionItemsJob.php | head -30
Copy code to clipboard
OUT
13:use Jiminny\Exceptions\RateLimitException;
51: GuzzleException|HttpBadRequestException|JsonException|RateLimitException|UnexpectedValueException $exception
56: $this->release(30);
Bash
Check retry/failure handling in GenerateAiCallScoringJob
IN
grep -n "RateLimitException\|retryUntil\|backoff\|maxExceptions\|maxTries\|release\|failed" /Users/lukas/jiminny/app/app/Component/AiCallScoring/Jobs/GenerateAiCallScoringJob.php | head -30
Copy code to clipboard
OUT
17:use Jiminny\Exceptions\RateLimitException;
68: RateLimitException |
75: $this->release(30);
Bash
Check retry config in MatchActivityCrmData
IN
grep -n "retryAfter\|RETRY_WINDOW\|retryUntil\|maxTries" /Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php
Copy code to clipboard
OUT
34: private const int RETRY_WINDOW_MINUTES = 30;
45: public function retryUntil(): \DateTimeInterface
47: return now()->addMinutes(self::RETRY_WINDOW_MINUTES);
77: return self::RETRY_WINDOW_MINUTES * 60 + 60;
Bash
Check the cache key format
IN
grep -n "getRateLimitCacheKey\|hubspot:ratelimit" /Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Client.php
Copy code to clipboard
OUT
78: $cacheKey = $this->getRateLimitCacheKey();
110: private function getRateLimitCacheKey(): string
112: return sprintf('hubspot:ratelimit:portal:%d', $this->config->getId());
Bash
Find other jobs that might use the rate limit middleware
IN
grep -rn "class.*Middleware\|HandleHubspotRateLimit" /Users/lukas/jiminny/app/app/Jobs --include="*.php" | grep -v "HandleHubspotRateLimit.php"
Copy code to clipboard
OUT
/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:18:use Jiminny\Jobs\Middleware\HandleHubspotRateLimit;
/Users/lukas/jiminny/app/app/Jobs/Crm/MatchActivityCrmData.php:42: return [new HandleHubspotRateLimit()];
Read
HubspotClientInterface.php
HubspotClientInterface.php
Thought for 73s
Thought for 73s
Now I have a complete picture. Here's my full analysis:
Review Summary
Review Summary
RuntimeException vs LogicException — Safe ✓
RuntimeException
vs
LogicException
— Safe ✓
The change is semantically correct and won't break anything.
LogicException
is for programmer errors (invalid arguments, contract violations). A rate limit from an external API is a runtime condition —
RuntimeException
is the right parent. All callers catch
RateLimitException
by name explicitly (union catches in
GenerateActionItemsJob
,
GenerateAiCallScoringJob
,
SummarizeTranscriptionJob
,
GenerateAiActivityTypeJob
) or check
instanceof RateLimitException
— none relies on the parent class type, so nothing breaks.
Issue 1 — Circuit breaker stores stale delay (most important bug)
Issue 1 — Circuit breaker stores stale delay (most important bug)
Client.php:94
Client.php:94
Copy code to clipboard
Redis::setex($cacheKey, $retryAfter, (string) $retryAfter);
The TTL is
$retryAfter
seconds, but the
stored value
is also the original
$retryAfter
. If a second job reads this cache 20 seconds later, it throws
RateLimitException(retryAfter=30)
and gets delayed 30 more seconds — even though only 10 remain. In a spike of 100 jobs, each subsequent job inflates its wait.
Fix:
store the absolute expiry timestamp, reconstruct the remaining delay when reading:
Copy code to clipboard
// on 429:
Redis::setex($cacheKey, $retryAfter, (string) (time() + $retryAfter));
// in the cached-read branch:
$remaining = max(1, (int) $cachedRetryAfter - time());
throw new RateLimitException('Hubspot rate limit (cached circuit-breaker)', $remaining);
Issue 2 — retryUntil() window may expire under sustained rate limiting
Issue 2 —
retryUntil()
window may expire under sustained rate limiting
MatchActivityCrmData.php:45-47
MatchActivityCrmData.php:45-47
retryUntil()
is calculated as
now() + 30 min
at
dispatch time
and stored in the job payload. With
MAX_RETRY_DELAY = 600s
, you only get ~3 rate-limit-triggered releases before the 30-minute window closes and the job is permanently failed. For a heavy 429 spike (daily limit, parsed as 600s), this can easily happen.
Consider increasing
RETRY_WINDOW_MINUTES
to 60 or more, or making it configurable. The
uniqueFor()
value should be updated to match.
Issue 3 — Only search() uses the circuit breaker, but other methods can still hit 429
Issue 3 — Only
search()
uses the circuit breaker, but other methods can still hit 429
Client.php:76-108
Client.php:76-108
executeRequest()
is only called from
search()
. Methods like
getOpportunityById()
,
batchReadObjects()
,
getContactByEmail()
bypass it entirely. If HubSpot's 429 is account-wide (not search-endpoint-specific), those methods will keep firing even while the circuit breaker is supposedly open. This is likely fine because the search endpoint has its own tighter quota (5 RPS), but it's worth being explicit in a comment.
Issue 4 — object $job type in middleware has no compile-time safety
Issue 4 —
object $job
type in middleware has no compile-time safety
HandleHubspotRateLimit.php:20
HandleHubspotRateLimit.php:20
Copy code to clipboard
public function handle(object $job, callable $next): void
Calling
$job->attempts()
and
$job->release()
on
object
will work at runtime since Laravel always passes jobs that use
InteractsWithQueue
, but PHPStan/psalm won't verify this and it could silently break in tests with bare mocks (as your test does use a
Job
mock that has
attempts()
— so the test is fine, but the real type contract is invisible). Minor, but worth tightening to
\Illuminate\Contracts\Queue\Job
.
What works well ✓
What works well ✓
RateLimitException
is caught by the middleware...
|
20285
|
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ /Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Client.php...
|
NULL
|
NULL
|
|
12976
|
576
|
15
|
2026-05-09T09:59:45.417834+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778320785417_m2.jpg...
|
Firefox
|
Finance Hub — Personal
|
True
|
finance-hub.lakylak.xyz/outpost.goauthentik.io/sig finance-hub.lakylak.xyz/outpost.goauthentik.io/sign_out...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Table: transaction_imports - db - Adminer
Table: transaction_imports - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
2
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Display settings
Sign out
Upload DSK Bank CSV
Upload DSK Bank CSV
Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.
Drop DSK Bank CSV files here
or click to select files — multiple files supported
Import complete
0
Imported
0
Skipped
16
Warnings
Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).
▾ Show 16 warnings
▾
Show
16
warning
s
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ", amount: 17.93, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 8.44, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 47.63, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 0.09, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 29.54, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА", amount: 14.27, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЧЦДГ МИЛА", amount: 460, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: "ПРЕВОД SEPA", payerAccount: "[IBAN]", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Debit: 10.22 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: null, amount: 10.22, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: "[CREDIT_CARD]", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: "ВЕДА ПЕЙРОЛ ООД", amount: 4325.26, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: "ВХОДЯЩ ПАРИЧЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR", date: new Date("2026-04-22T00:00:00.000Z"), type: null, card: null, recipient: "МАРТИНА СВЕТОСЛАВОВА КОВАЛИК", amount: 1000, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: "НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 5.02 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 5.02, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 15.46 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 15.46, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 9.04 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 9.04, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR", date: new Date("2026-05-08T16:32:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR", amount: 67.81, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR", date: new Date("2026-05-07T06:02:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIA CBA EKO MARKET", amount: 5.51, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR", date: new Date("2026-05-06T10:16:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "POL BALICE Lagardere Travel R KR3", amount: 5.49, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
View imported transactions
View imported transactions...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.080784574,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DNS / Nameservers | Hostinger","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DNS / Nameservers | Hostinger","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.053856384,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.037898935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: archive.db","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.040724736,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: db.sqlite","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.03756649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.11469415,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AFFiNE - All In One KnowledgeOS","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AFFiNE - All In One KnowledgeOS","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.05851064,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"bounds":{"left":0.0,"top":0.3463687,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All docs · AFFiNE","depth":5,"bounds":{"left":0.013297873,"top":0.3575419,"width":0.029587766,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Payments Logger","depth":4,"bounds":{"left":0.0,"top":0.3790902,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments Logger","depth":5,"bounds":{"left":0.013297873,"top":0.39026338,"width":0.030086435,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"bounds":{"left":0.0,"top":0.41181165,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.013297873,"top":0.42298484,"width":0.06898271,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"(25) Quora","depth":4,"bounds":{"left":0.0,"top":0.4445331,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(25) Quora","depth":5,"bounds":{"left":0.013297873,"top":0.4557063,"width":0.018949468,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"bounds":{"left":0.0,"top":0.4772546,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"bounds":{"left":0.013297873,"top":0.4884278,"width":0.028091755,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"bounds":{"left":0.0,"top":0.509976,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Finance Hub","depth":5,"bounds":{"left":0.013297873,"top":0.5211492,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"bounds":{"left":0.0,"top":0.54269755,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Finance Hub","depth":5,"bounds":{"left":0.013297873,"top":0.55387074,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.10139628,"top":0.54988027,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Table: transaction_imports - db - Adminer","depth":4,"bounds":{"left":0.0,"top":0.575419,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Table: transaction_imports - db - Adminer","depth":5,"bounds":{"left":0.013297873,"top":0.5865922,"width":0.0731383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"bounds":{"left":0.0,"top":0.60814047,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"bounds":{"left":0.013297873,"top":0.61931366,"width":0.09059176,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":4,"bounds":{"left":0.0,"top":0.6408619,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":5,"bounds":{"left":0.013297873,"top":0.6520351,"width":0.113696806,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"bounds":{"left":0.0,"top":0.6735834,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"bounds":{"left":0.013297873,"top":0.6847566,"width":0.016788565,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":4,"bounds":{"left":0.0,"top":0.70630485,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":5,"bounds":{"left":0.013297873,"top":0.71747804,"width":0.10239362,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"bounds":{"left":0.0,"top":0.7390263,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"bounds":{"left":0.013297873,"top":0.7501995,"width":0.016788565,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":4,"bounds":{"left":0.0,"top":0.7717478,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":5,"bounds":{"left":0.013297873,"top":0.782921,"width":0.098902926,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Code | Claude Platform","depth":4,"bounds":{"left":0.0,"top":0.8044693,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Code | Claude Platform","depth":5,"bounds":{"left":0.013297873,"top":0.8156425,"width":0.053357713,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude","depth":4,"bounds":{"left":0.0,"top":0.83719075,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude","depth":5,"bounds":{"left":0.013297873,"top":0.84836394,"width":0.012134309,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.87150836,"width":0.108211435,"height":0.025538707},"on_screen":true,"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.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Finance Hub","depth":8,"bounds":{"left":0.22539894,"top":0.0622506,"width":0.032081116,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finance Hub","depth":9,"bounds":{"left":0.22539894,"top":0.06264964,"width":0.032081116,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":9,"bounds":{"left":0.22539894,"top":0.07861133,"width":0.002493351,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"transaction","depth":9,"bounds":{"left":0.2278923,"top":0.07861133,"width":0.022273935,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":9,"bounds":{"left":0.25016624,"top":0.07861133,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Payments","depth":8,"bounds":{"left":0.38613698,"top":0.06384677,"width":0.036070477,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments","depth":10,"bounds":{"left":0.39677528,"top":0.0698324,"width":0.02144282,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Upload CSV","depth":8,"bounds":{"left":0.42287233,"top":0.06384677,"width":0.04105718,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Upload CSV","depth":10,"bounds":{"left":0.43351063,"top":0.0698324,"width":0.02642952,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Display settings","depth":8,"bounds":{"left":0.5924202,"top":0.06384677,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Sign out","depth":8,"bounds":{"left":0.6050532,"top":0.06384677,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upload DSK Bank CSV","depth":8,"bounds":{"left":0.3018617,"top":0.11811652,"width":0.22340426,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upload DSK Bank CSV","depth":9,"bounds":{"left":0.3018617,"top":0.12090982,"width":0.062832445,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.","depth":9,"bounds":{"left":0.3018617,"top":0.14485236,"width":0.20777926,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drop DSK Bank CSV files here","depth":10,"bounds":{"left":0.3806516,"top":0.2773344,"width":0.06582447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or click to select files — multiple files supported","depth":10,"bounds":{"left":0.36851728,"top":0.29569036,"width":0.09009308,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import complete","depth":9,"bounds":{"left":0.3181516,"top":0.3858739,"width":0.04089096,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":9,"bounds":{"left":0.33976063,"top":0.42098963,"width":0.005319149,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Imported","depth":9,"bounds":{"left":0.33394283,"top":0.44573024,"width":0.016954787,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":9,"bounds":{"left":0.41090426,"top":0.42098963,"width":0.005319149,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skipped","depth":9,"bounds":{"left":0.40591756,"top":0.44573024,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":9,"bounds":{"left":0.4800532,"top":0.42098963,"width":0.00930851,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Warnings","depth":9,"bounds":{"left":0.4758976,"top":0.44573024,"width":0.01761968,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).","depth":9,"bounds":{"left":0.30884308,"top":0.47525936,"width":0.14694148,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"▾ Show 16 warnings","depth":9,"bounds":{"left":0.30884308,"top":0.49720672,"width":0.20944148,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"▾","depth":10,"bounds":{"left":0.30884308,"top":0.49960095,"width":0.0034906915,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show","depth":10,"bounds":{"left":0.31233376,"top":0.4980048,"width":0.011469414,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":10,"bounds":{"left":0.3238032,"top":0.4980048,"width":0.0043218085,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"warning","depth":10,"bounds":{"left":0.328125,"top":0.4980048,"width":0.015957447,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":10,"bounds":{"left":0.34408244,"top":0.4980048,"width":0.0021609042,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ\", amount: 17.93, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG91STSA93000004594021\", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.30884308,"top":0.5171588,"width":0.2087766,"height":0.16480447},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"С0ФИЙСКА ВОДА ДСК ДИРЕКТ\", amount: 8.44, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG03STSA93000045940400\", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.30884308,"top":0.6847566,"width":0.2087766,"height":0.16480447},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ\", amount: 47.63, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG15STSA93000004594031\", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.30884308,"top":0.85235435,"width":0.20628324,"height":0.14764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ\", amount: 0.09, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG15STSA93000004594031\", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.30884308,"top":1.0,"width":0.20628324,"height":-0.019952059},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"С0ФИЙСКА ВОДА ДСК ДИРЕКТ\", amount: 29.54, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG03STSA93000045940400\", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА\", amount: 14.27, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG57STSA93000004594051\", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЧЦДГ МИЛА\", amount: 460, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: \"ПРЕВОД SEPA\", payerAccount: \"BG43UBBS81551007780277\", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 30.04.2026 | Debit: 10.22 EUR\", date: new Date(\"2026-04-30T00:00:00.000Z\"), type: null, card: null, recipient: null, amount: 10.22, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: \"7291133030269999\", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR\", date: new Date(\"2026-04-30T00:00:00.000Z\"), type: null, card: null, recipient: \"ВЕДА ПЕЙРОЛ ООД\", amount: 4325.26, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: \"ВХОДЯЩ ПАРИЧЕН ПРЕВОД\", payerAccount: \"BG65UNCR70001525823547\", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR\", date: new Date(\"2026-04-22T00:00:00.000Z\"), type: null, card: null, recipient: \"МАРТИНА СВЕТОСЛАВОВА КОВАЛИК\", amount: 1000, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: \"НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД\", payerAccount: \"BG28UNCR70001522249763\", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 5.02 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 5.02, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 15.46 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 15.46, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 9.04 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 9.04, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR\", date: new Date(\"2026-05-08T16:32:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR\", amount: 67.81, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR\", date: new Date(\"2026-05-07T06:02:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"BGR SOFIA CBA EKO MARKET\", amount: 5.51, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR\", date: new Date(\"2026-05-06T10:16:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"POL BALICE Lagardere Travel R KR3\", amount: 5.49, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View imported transactions","depth":8,"bounds":{"left":0.30884308,"top":0.62849164,"width":0.067652926,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View imported transactions","depth":9,"bounds":{"left":0.31615692,"top":0.62968874,"width":0.060339097,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9082425790734312014
|
-4983593754868435208
|
click
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Table: transaction_imports - db - Adminer
Table: transaction_imports - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
2
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Display settings
Sign out
Upload DSK Bank CSV
Upload DSK Bank CSV
Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.
Drop DSK Bank CSV files here
or click to select files — multiple files supported
Import complete
0
Imported
0
Skipped
16
Warnings
Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).
▾ Show 16 warnings
▾
Show
16
warning
s
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ", amount: 17.93, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 8.44, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 47.63, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 0.09, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 29.54, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА", amount: 14.27, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЧЦДГ МИЛА", amount: 460, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: "ПРЕВОД SEPA", payerAccount: "[IBAN]", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Debit: 10.22 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: null, amount: 10.22, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: "[CREDIT_CARD]", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: "ВЕДА ПЕЙРОЛ ООД", amount: 4325.26, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: "ВХОДЯЩ ПАРИЧЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR", date: new Date("2026-04-22T00:00:00.000Z"), type: null, card: null, recipient: "МАРТИНА СВЕТОСЛАВОВА КОВАЛИК", amount: 1000, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: "НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 5.02 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 5.02, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 15.46 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 15.46, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 9.04 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 9.04, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR", date: new Date("2026-05-08T16:32:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR", amount: 67.81, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR", date: new Date("2026-05-07T06:02:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIA CBA EKO MARKET", amount: 5.51, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR", date: new Date("2026-05-06T10:16:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "POL BALICE Lagardere Travel R KR3", amount: 5.49, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
View imported transactions
View imported transactions...
|
12975
|
NULL
|
NULL
|
NULL
|
|
12977
|
575
|
11
|
2026-05-09T09:59:48.037261+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778320788037_m1.jpg...
|
Firefox
|
Finance Hub — Personal
|
True
|
finance-hub.lakylak.xyz/outpost.goauthentik.io/sig finance-hub.lakylak.xyz/outpost.goauthentik.io/sign_out...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Table: transaction_imports - db - Adminer
Table: transaction_imports - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
2
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Display settings
Sign out
Upload DSK Bank CSV
Upload DSK Bank CSV
Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.
Drop DSK Bank CSV files here
or click to select files — multiple files supported
Import complete
0
Imported
0
Skipped
16
Warnings
Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).
▾ Show 16 warnings
▾
Show
16
warning
s
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ", amount: 17.93, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 8.44, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 47.63, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 0.09, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 29.54, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА", amount: 14.27, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЧЦДГ МИЛА", amount: 460, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: "ПРЕВОД SEPA", payerAccount: "[IBAN]", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Debit: 10.22 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: null, amount: 10.22, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: "[CREDIT_CARD]", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: "ВЕДА ПЕЙРОЛ ООД", amount: 4325.26, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: "ВХОДЯЩ ПАРИЧЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR", date: new Date("2026-04-22T00:00:00.000Z"), type: null, card: null, recipient: "МАРТИНА СВЕТОСЛАВОВА КОВАЛИК", amount: 1000, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: "НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 5.02 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 5.02, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 15.46 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 15.46, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 9.04 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 9.04, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR", date: new Date("2026-05-08T16:32:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR", amount: 67.81, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR", date: new Date("2026-05-07T06:02:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIA CBA EKO MARKET", amount: 5.51, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR", date: new Date("2026-05-06T10:16:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "POL BALICE Lagardere Travel R KR3", amount: 5.49, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
View imported transactions
View imported transactions...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DNS / Nameservers | Hostinger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DNS / Nameservers | Hostinger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: archive.db","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: db.sqlite","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AFFiNE - All In One KnowledgeOS","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AFFiNE - All In One KnowledgeOS","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All docs · AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Payments Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"(25) Quora","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(25) Quora","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Table: transaction_imports - db - Adminer","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Table: transaction_imports - db - Adminer","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Code | Claude Platform","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Code | Claude Platform","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Finance Hub","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finance Hub","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"transaction","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Payments","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Upload CSV","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Upload CSV","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Display settings","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Sign out","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upload DSK Bank CSV","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upload DSK Bank CSV","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drop DSK Bank CSV files here","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or click to select files — multiple files supported","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import complete","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Imported","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skipped","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Warnings","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"▾ Show 16 warnings","depth":9,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"▾","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"warning","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ\", amount: 17.93, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG91STSA93000004594021\", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"С0ФИЙСКА ВОДА ДСК ДИРЕКТ\", amount: 8.44, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG03STSA93000045940400\", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ\", amount: 47.63, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG15STSA93000004594031\", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ\", amount: 0.09, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG15STSA93000004594031\", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.027777778,"width":0.43090278,"height":0.22944444},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"С0ФИЙСКА ВОДА ДСК ДИРЕКТ\", amount: 29.54, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG03STSA93000045940400\", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.2611111,"width":0.43611112,"height":0.22944444},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА\", amount: 14.27, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG57STSA93000004594051\", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.49444443,"width":0.43611112,"height":0.22944444},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЧЦДГ МИЛА\", amount: 460, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: \"ПРЕВОД SEPA\", payerAccount: \"BG43UBBS81551007780277\", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.7277778,"width":0.43611112,"height":0.21166667},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 30.04.2026 | Debit: 10.22 EUR\", date: new Date(\"2026-04-30T00:00:00.000Z\"), type: null, card: null, recipient: null, amount: 10.22, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: \"7291133030269999\", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.9433333,"width":0.43611112,"height":0.056666672},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR\", date: new Date(\"2026-04-30T00:00:00.000Z\"), type: null, card: null, recipient: \"ВЕДА ПЕЙРОЛ ООД\", amount: 4325.26, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: \"ВХОДЯЩ ПАРИЧЕН ПРЕВОД\", payerAccount: \"BG65UNCR70001525823547\", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR\", date: new Date(\"2026-04-22T00:00:00.000Z\"), type: null, card: null, recipient: \"МАРТИНА СВЕТОСЛАВОВА КОВАЛИК\", amount: 1000, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: \"НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД\", payerAccount: \"BG28UNCR70001522249763\", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 5.02 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 5.02, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 15.46 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 15.46, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 9.04 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 9.04, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR\", date: new Date(\"2026-05-08T16:32:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR\", amount: 67.81, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR\", date: new Date(\"2026-05-07T06:02:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"BGR SOFIA CBA EKO MARKET\", amount: 5.51, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR\", date: new Date(\"2026-05-06T10:16:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"POL BALICE Lagardere Travel R KR3\", amount: 5.49, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View imported transactions","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View imported transactions","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9082425790734312014
|
-4983593754868435208
|
click
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Table: transaction_imports - db - Adminer
Table: transaction_imports - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
2
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Display settings
Sign out
Upload DSK Bank CSV
Upload DSK Bank CSV
Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.
Drop DSK Bank CSV files here
or click to select files — multiple files supported
Import complete
0
Imported
0
Skipped
16
Warnings
Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).
▾ Show 16 warnings
▾
Show
16
warning
s
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ", amount: 17.93, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 8.44, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 47.63, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 0.09, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 29.54, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА", amount: 14.27, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЧЦДГ МИЛА", amount: 460, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: "ПРЕВОД SEPA", payerAccount: "[IBAN]", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Debit: 10.22 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: null, amount: 10.22, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: "[CREDIT_CARD]", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: "ВЕДА ПЕЙРОЛ ООД", amount: 4325.26, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: "ВХОДЯЩ ПАРИЧЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR", date: new Date("2026-04-22T00:00:00.000Z"), type: null, card: null, recipient: "МАРТИНА СВЕТОСЛАВОВА КОВАЛИК", amount: 1000, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: "НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 5.02 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 5.02, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 15.46 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 15.46, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 9.04 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 9.04, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR", date: new Date("2026-05-08T16:32:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR", amount: 67.81, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR", date: new Date("2026-05-07T06:02:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIA CBA EKO MARKET", amount: 5.51, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR", date: new Date("2026-05-06T10:16:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "POL BALICE Lagardere Travel R KR3", amount: 5.49, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
View imported transactions
View imported transactions...
|
12974
|
NULL
|
NULL
|
NULL
|
|
12993
|
575
|
21
|
2026-05-09T10:02:59.187054+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778320979187_m1.jpg...
|
Firefox
|
Finance Hub — Personal
|
True
|
finance-hub.lakylak.xyz/outpost.goauthentik.io/sig finance-hub.lakylak.xyz/outpost.goauthentik.io/sign_out...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Table: transaction_imports - db - Adminer
Table: transaction_imports - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
2
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Display settings
Sign out
Upload DSK Bank CSV
Upload DSK Bank CSV
Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.
Drop DSK Bank CSV files here
or click to select files — multiple files supported
Import complete
0
Imported
0
Skipped
16
Warnings
Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).
▾ Show 16 warnings
▾
Show
16
warning
s
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ", amount: 17.93, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 8.44, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 47.63, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 0.09, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 29.54, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА", amount: 14.27, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЧЦДГ МИЛА", amount: 460, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: "ПРЕВОД SEPA", payerAccount: "[IBAN]", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Debit: 10.22 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: null, amount: 10.22, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: "[CREDIT_CARD]", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: "ВЕДА ПЕЙРОЛ ООД", amount: 4325.26, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: "ВХОДЯЩ ПАРИЧЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR", date: new Date("2026-04-22T00:00:00.000Z"), type: null, card: null, recipient: "МАРТИНА СВЕТОСЛАВОВА КОВАЛИК", amount: 1000, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: "НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 5.02 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 5.02, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 15.46 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 15.46, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 9.04 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 9.04, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR", date: new Date("2026-05-08T16:32:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR", amount: 67.81, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR", date: new Date("2026-05-07T06:02:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIA CBA EKO MARKET", amount: 5.51, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR", date: new Date("2026-05-06T10:16:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "POL BALICE Lagardere Travel R KR3", amount: 5.49, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
View imported transactions
View imported transactions...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DNS / Nameservers | Hostinger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DNS / Nameservers | Hostinger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: archive.db","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: db.sqlite","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AFFiNE - All In One KnowledgeOS","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AFFiNE - All In One KnowledgeOS","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All docs · AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Payments Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"(25) Quora","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(25) Quora","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Table: transaction_imports - db - Adminer","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Table: transaction_imports - db - Adminer","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Code | Claude Platform","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Code | Claude Platform","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Finance Hub","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finance Hub","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"transaction","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Payments","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Upload CSV","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Upload CSV","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Display settings","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Sign out","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upload DSK Bank CSV","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upload DSK Bank CSV","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drop DSK Bank CSV files here","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or click to select files — multiple files supported","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import complete","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Imported","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skipped","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Warnings","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"▾ Show 16 warnings","depth":9,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"▾","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"warning","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ\", amount: 17.93, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG91STSA93000004594021\", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"С0ФИЙСКА ВОДА ДСК ДИРЕКТ\", amount: 8.44, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG03STSA93000045940400\", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ\", amount: 47.63, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG15STSA93000004594031\", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ\", amount: 0.09, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG15STSA93000004594031\", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.027777778,"width":0.43090278,"height":0.22944444},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"С0ФИЙСКА ВОДА ДСК ДИРЕКТ\", amount: 29.54, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG03STSA93000045940400\", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.2611111,"width":0.43611112,"height":0.22944444},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА\", amount: 14.27, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG57STSA93000004594051\", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.49444443,"width":0.43611112,"height":0.22944444},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЧЦДГ МИЛА\", amount: 460, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: \"ПРЕВОД SEPA\", payerAccount: \"BG43UBBS81551007780277\", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.7277778,"width":0.43611112,"height":0.21166667},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 30.04.2026 | Debit: 10.22 EUR\", date: new Date(\"2026-04-30T00:00:00.000Z\"), type: null, card: null, recipient: null, amount: 10.22, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: \"7291133030269999\", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.08055556,"top":0.9433333,"width":0.43611112,"height":0.056666672},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR\", date: new Date(\"2026-04-30T00:00:00.000Z\"), type: null, card: null, recipient: \"ВЕДА ПЕЙРОЛ ООД\", amount: 4325.26, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: \"ВХОДЯЩ ПАРИЧЕН ПРЕВОД\", payerAccount: \"BG65UNCR70001525823547\", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR\", date: new Date(\"2026-04-22T00:00:00.000Z\"), type: null, card: null, recipient: \"МАРТИНА СВЕТОСЛАВОВА КОВАЛИК\", amount: 1000, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: \"НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД\", payerAccount: \"BG28UNCR70001522249763\", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 5.02 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 5.02, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 15.46 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 15.46, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 9.04 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 9.04, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR\", date: new Date(\"2026-05-08T16:32:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR\", amount: 67.81, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR\", date: new Date(\"2026-05-07T06:02:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"BGR SOFIA CBA EKO MARKET\", amount: 5.51, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR\", date: new Date(\"2026-05-06T10:16:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"POL BALICE Lagardere Travel R KR3\", amount: 5.49, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View imported transactions","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View imported transactions","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9082425790734312014
|
-4983593754868435208
|
visual_change
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Table: transaction_imports - db - Adminer
Table: transaction_imports - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
2
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Display settings
Sign out
Upload DSK Bank CSV
Upload DSK Bank CSV
Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.
Drop DSK Bank CSV files here
or click to select files — multiple files supported
Import complete
0
Imported
0
Skipped
16
Warnings
Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).
▾ Show 16 warnings
▾
Show
16
warning
s
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ", amount: 17.93, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 8.44, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 47.63, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 0.09, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 29.54, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА", amount: 14.27, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЧЦДГ МИЛА", amount: 460, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: "ПРЕВОД SEPA", payerAccount: "[IBAN]", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Debit: 10.22 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: null, amount: 10.22, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: "[CREDIT_CARD]", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: "ВЕДА ПЕЙРОЛ ООД", amount: 4325.26, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: "ВХОДЯЩ ПАРИЧЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR", date: new Date("2026-04-22T00:00:00.000Z"), type: null, card: null, recipient: "МАРТИНА СВЕТОСЛАВОВА КОВАЛИК", amount: 1000, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: "НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 5.02 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 5.02, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 15.46 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 15.46, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 9.04 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 9.04, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR", date: new Date("2026-05-08T16:32:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR", amount: 67.81, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR", date: new Date("2026-05-07T06:02:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIA CBA EKO MARKET", amount: 5.51, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR", date: new Date("2026-05-06T10:16:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "POL BALICE Lagardere Travel R KR3", amount: 5.49, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
View imported transactions
View imported transactions...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
12994
|
576
|
22
|
2026-05-09T10:02:59.681239+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778320979681_m2.jpg...
|
Firefox
|
Finance Hub — Personal
|
True
|
finance-hub.lakylak.xyz/outpost.goauthentik.io/sig finance-hub.lakylak.xyz/outpost.goauthentik.io/sign_out...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Table: transaction_imports - db - Adminer
Table: transaction_imports - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
2
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Display settings
Sign out
Upload DSK Bank CSV
Upload DSK Bank CSV
Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.
Drop DSK Bank CSV files here
or click to select files — multiple files supported
Import complete
0
Imported
0
Skipped
16
Warnings
Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).
▾ Show 16 warnings
▾
Show
16
warning
s
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ", amount: 17.93, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 8.44, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 47.63, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 0.09, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 29.54, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА", amount: 14.27, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЧЦДГ МИЛА", amount: 460, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: "ПРЕВОД SEPA", payerAccount: "[IBAN]", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Debit: 10.22 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: null, amount: 10.22, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: "[CREDIT_CARD]", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: "ВЕДА ПЕЙРОЛ ООД", amount: 4325.26, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: "ВХОДЯЩ ПАРИЧЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR", date: new Date("2026-04-22T00:00:00.000Z"), type: null, card: null, recipient: "МАРТИНА СВЕТОСЛАВОВА КОВАЛИК", amount: 1000, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: "НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 5.02 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 5.02, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 15.46 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 15.46, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 9.04 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 9.04, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR", date: new Date("2026-05-08T16:32:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR", amount: 67.81, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR", date: new Date("2026-05-07T06:02:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIA CBA EKO MARKET", amount: 5.51, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR", date: new Date("2026-05-06T10:16:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "POL BALICE Lagardere Travel R KR3", amount: 5.49, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
View imported transactions
View imported transactions...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.080784574,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DNS / Nameservers | Hostinger","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DNS / Nameservers | Hostinger","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.053856384,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.037898935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: archive.db","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.040724736,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: db.sqlite","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.03756649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.11469415,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AFFiNE - All In One KnowledgeOS","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AFFiNE - All In One KnowledgeOS","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.05851064,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"bounds":{"left":0.0,"top":0.3463687,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All docs · AFFiNE","depth":5,"bounds":{"left":0.013297873,"top":0.3575419,"width":0.029587766,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Payments Logger","depth":4,"bounds":{"left":0.0,"top":0.3790902,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments Logger","depth":5,"bounds":{"left":0.013297873,"top":0.39026338,"width":0.030086435,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"bounds":{"left":0.0,"top":0.41181165,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.013297873,"top":0.42298484,"width":0.06898271,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"(25) Quora","depth":4,"bounds":{"left":0.0,"top":0.4445331,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(25) Quora","depth":5,"bounds":{"left":0.013297873,"top":0.4557063,"width":0.018949468,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"bounds":{"left":0.0,"top":0.4772546,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"bounds":{"left":0.013297873,"top":0.4884278,"width":0.028091755,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"bounds":{"left":0.0,"top":0.509976,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Finance Hub","depth":5,"bounds":{"left":0.013297873,"top":0.5211492,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"bounds":{"left":0.0,"top":0.54269755,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Finance Hub","depth":5,"bounds":{"left":0.013297873,"top":0.55387074,"width":0.021609042,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.10139628,"top":0.54988027,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Table: transaction_imports - db - Adminer","depth":4,"bounds":{"left":0.0,"top":0.575419,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Table: transaction_imports - db - Adminer","depth":5,"bounds":{"left":0.013297873,"top":0.5865922,"width":0.0731383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"bounds":{"left":0.0,"top":0.60814047,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"bounds":{"left":0.013297873,"top":0.61931366,"width":0.09059176,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":4,"bounds":{"left":0.0,"top":0.6408619,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":5,"bounds":{"left":0.013297873,"top":0.6520351,"width":0.113696806,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"bounds":{"left":0.0,"top":0.6735834,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"bounds":{"left":0.013297873,"top":0.6847566,"width":0.016788565,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":4,"bounds":{"left":0.0,"top":0.70630485,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":5,"bounds":{"left":0.013297873,"top":0.71747804,"width":0.10239362,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"bounds":{"left":0.0,"top":0.7390263,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"bounds":{"left":0.013297873,"top":0.7501995,"width":0.016788565,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":4,"bounds":{"left":0.0,"top":0.7717478,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":5,"bounds":{"left":0.013297873,"top":0.782921,"width":0.098902926,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Code | Claude Platform","depth":4,"bounds":{"left":0.0,"top":0.8044693,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Code | Claude Platform","depth":5,"bounds":{"left":0.013297873,"top":0.8156425,"width":0.053357713,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude","depth":4,"bounds":{"left":0.0,"top":0.83719075,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude","depth":5,"bounds":{"left":0.013297873,"top":0.84836394,"width":0.012134309,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.87150836,"width":0.108211435,"height":0.025538707},"on_screen":true,"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.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Finance Hub","depth":8,"bounds":{"left":0.22539894,"top":0.0622506,"width":0.032081116,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finance Hub","depth":9,"bounds":{"left":0.22539894,"top":0.06264964,"width":0.032081116,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":9,"bounds":{"left":0.22539894,"top":0.07861133,"width":0.002493351,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"transaction","depth":9,"bounds":{"left":0.2278923,"top":0.07861133,"width":0.022273935,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":9,"bounds":{"left":0.25016624,"top":0.07861133,"width":0.0019946808,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Payments","depth":8,"bounds":{"left":0.38613698,"top":0.06384677,"width":0.036070477,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments","depth":10,"bounds":{"left":0.39677528,"top":0.0698324,"width":0.02144282,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Upload CSV","depth":8,"bounds":{"left":0.42287233,"top":0.06384677,"width":0.04105718,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Upload CSV","depth":10,"bounds":{"left":0.43351063,"top":0.0698324,"width":0.02642952,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Display settings","depth":8,"bounds":{"left":0.5924202,"top":0.06384677,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Sign out","depth":8,"bounds":{"left":0.6050532,"top":0.06384677,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upload DSK Bank CSV","depth":8,"bounds":{"left":0.3018617,"top":0.11811652,"width":0.22340426,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upload DSK Bank CSV","depth":9,"bounds":{"left":0.3018617,"top":0.12090982,"width":0.062832445,"height":0.01715882},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.","depth":9,"bounds":{"left":0.3018617,"top":0.14485236,"width":0.20777926,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drop DSK Bank CSV files here","depth":10,"bounds":{"left":0.3806516,"top":0.2773344,"width":0.06582447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or click to select files — multiple files supported","depth":10,"bounds":{"left":0.36851728,"top":0.29569036,"width":0.09009308,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import complete","depth":9,"bounds":{"left":0.3181516,"top":0.3858739,"width":0.04089096,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":9,"bounds":{"left":0.33976063,"top":0.42098963,"width":0.005319149,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Imported","depth":9,"bounds":{"left":0.33394283,"top":0.44573024,"width":0.016954787,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":9,"bounds":{"left":0.41090426,"top":0.42098963,"width":0.005319149,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skipped","depth":9,"bounds":{"left":0.40591756,"top":0.44573024,"width":0.015292553,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":9,"bounds":{"left":0.4800532,"top":0.42098963,"width":0.00930851,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Warnings","depth":9,"bounds":{"left":0.4758976,"top":0.44573024,"width":0.01761968,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).","depth":9,"bounds":{"left":0.30884308,"top":0.47525936,"width":0.14694148,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"▾ Show 16 warnings","depth":9,"bounds":{"left":0.30884308,"top":0.49720672,"width":0.20944148,"height":0.0131683955},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"▾","depth":10,"bounds":{"left":0.30884308,"top":0.49960095,"width":0.0034906915,"height":0.008379889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show","depth":10,"bounds":{"left":0.31233376,"top":0.4980048,"width":0.011469414,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":10,"bounds":{"left":0.3238032,"top":0.4980048,"width":0.0043218085,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"warning","depth":10,"bounds":{"left":0.328125,"top":0.4980048,"width":0.015957447,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":10,"bounds":{"left":0.34408244,"top":0.4980048,"width":0.0021609042,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ\", amount: 17.93, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG91STSA93000004594021\", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.30884308,"top":0.5171588,"width":0.2087766,"height":0.16480447},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"С0ФИЙСКА ВОДА ДСК ДИРЕКТ\", amount: 8.44, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG03STSA93000045940400\", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.30884308,"top":0.6847566,"width":0.2087766,"height":0.16480447},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ\", amount: 47.63, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG15STSA93000004594031\", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.30884308,"top":0.85235435,"width":0.20628324,"height":0.14764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ\", amount: 0.09, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG15STSA93000004594031\", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"bounds":{"left":0.30884308,"top":1.0,"width":0.20628324,"height":-0.019952059},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"С0ФИЙСКА ВОДА ДСК ДИРЕКТ\", amount: 29.54, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG03STSA93000045940400\", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА\", amount: 14.27, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: \"КОМУНАЛНИ УСЛУГИ\", payerAccount: \"BG57STSA93000004594051\", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR\", date: new Date(\"2026-05-04T00:00:00.000Z\"), type: null, card: null, recipient: \"ЧЦДГ МИЛА\", amount: 460, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: \"ПРЕВОД SEPA\", payerAccount: \"BG43UBBS81551007780277\", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 30.04.2026 | Debit: 10.22 EUR\", date: new Date(\"2026-04-30T00:00:00.000Z\"), type: null, card: null, recipient: null, amount: 10.22, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: \"7291133030269999\", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR\", date: new Date(\"2026-04-30T00:00:00.000Z\"), type: null, card: null, recipient: \"ВЕДА ПЕЙРОЛ ООД\", amount: 4325.26, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: \"ВХОДЯЩ ПАРИЧЕН ПРЕВОД\", payerAccount: \"BG65UNCR70001525823547\", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR\", date: new Date(\"2026-04-22T00:00:00.000Z\"), type: null, card: null, recipient: \"МАРТИНА СВЕТОСЛАВОВА КОВАЛИК\", amount: 1000, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: \"НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД\", payerAccount: \"BG28UNCR70001522249763\", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 5.02 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 5.02, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 15.46 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 15.46, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Debit: 9.04 EUR\", date: new Date(\"2026-05-08T00:00:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: null, amount: 9.04, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR\", date: new Date(\"2026-05-08T16:32:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR\", amount: 67.81, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR\", date: new Date(\"2026-05-07T06:02:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"BGR SOFIA CBA EKO MARKET\", amount: 5.51, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: \"Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR\", date: new Date(\"2026-05-06T10:16:00.000Z\"), type: null, card: \"400915xxxxxx4447\", recipient: \"POL BALICE Lagardere Travel R KR3\", amount: 5.49, currency: \"EUR\", balance: null, source: \"UPLOAD\", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: \"КАРТОВА ОПЕРАЦИЯ\", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View imported transactions","depth":8,"bounds":{"left":0.30884308,"top":0.62849164,"width":0.067652926,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View imported transactions","depth":9,"bounds":{"left":0.31615692,"top":0.62968874,"width":0.060339097,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9082425790734312014
|
-4983593754868435208
|
visual_change
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox - [EMAIL] - Gmail
Inbox - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Table: transaction_imports - db - Adminer
Table: transaction_imports - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
2
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Display settings
Sign out
Upload DSK Bank CSV
Upload DSK Bank CSV
Import transactions from DSK Bank CSV exports. Multiple files are merged automatically. Internal transfers are skipped. Tags are auto-assigned based on payee and description.
Drop DSK Bank CSV files here
or click to select files — multiple files supported
Import complete
0
Imported
0
Skipped
16
Warnings
Skipped rows are internal bank transfers (ТРАНСФЕР СОБСТВЕНИ СМЕТКИ).
▾ Show 16 warnings
▾
Show
16
warning
s
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ | Debit: 17.93 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "КОМУНАЛНИ РАЗХОДИ ЕЛ. КАНАЛИ", amount: 17.93, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 17.93, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 1, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 8.44 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 8.44, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 8.44, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 2, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 47.63 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 47.63, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 47.63, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 3, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ | Debit: 0.09 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЕЛЕКТPОХОЛДПPОДАЖБИ/ДСКДИРЕКТ/ЕЛ.ЕНЕРГИЯ", amount: 0.09, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 0.09, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 4, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: С0ФИЙСКА ВОДА ДСК ДИРЕКТ | Debit: 29.54 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "С0ФИЙСКА ВОДА ДСК ДИРЕКТ", amount: 29.54, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 29.54, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 5, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: КОМУНАЛНИ УСЛУГИ | Payee: ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА | Debit: 14.27 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ОВЕГАЗ МРЕЖИ АД-ЕЛЕКТРОННИ КАНАЛИ И КАСА", amount: 14.27, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 14.27, ~~~~~~~~ creditBgn: null, transactionType: "КОМУНАЛНИ УСЛУГИ", payerAccount: "[IBAN]", transactionId: 6, tags: { connect: [ { id: 2 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 04.05.2026 | Type: ПРЕВОД SEPA | Payee: ЧЦДГ МИЛА | Debit: 460 EUR", date: new Date("2026-05-04T00:00:00.000Z"), type: null, card: null, recipient: "ЧЦДГ МИЛА", amount: 460, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 460, ~~~~~~~~ creditBgn: null, transactionType: "ПРЕВОД SEPA", payerAccount: "[IBAN]", transactionId: 7, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Debit: 10.22 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: null, amount: 10.22, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 10.22, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: "[CREDIT_CARD]", transactionId: 8, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 30.04.2026 | Type: ВХОДЯЩ ПАРИЧЕН ПРЕВОД | Payee: ВЕДА ПЕЙРОЛ ООД | Credit: 4325.26 EUR", date: new Date("2026-04-30T00:00:00.000Z"), type: null, card: null, recipient: "ВЕДА ПЕЙРОЛ ООД", amount: 4325.26, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 4325.26, transactionType: "ВХОДЯЩ ПАРИЧЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 9, tags: { connect: [ { id: 3 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 22.04.2026 | Type: НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД | Payee: МАРТИНА СВЕТОСЛАВОВА КОВАЛИК | Credit: 1000 EUR", date: new Date("2026-04-22T00:00:00.000Z"), type: null, card: null, recipient: "МАРТИНА СВЕТОСЛАВОВА КОВАЛИК", amount: 1000, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: null, ~~~~~~~~ creditBgn: 1000, transactionType: "НЕЗАБАВЕН КРЕДИТЕН ПРЕВОД", payerAccount: "[IBAN]", transactionId: 10, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 5.02 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 5.02, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.02, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 11, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 15.46 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 15.46, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 15.46, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 12, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Debit: 9.04 EUR", date: new Date("2026-05-08T00:00:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: null, amount: 9.04, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 9.04, ~~~~~~~~ creditBgn: null, transactionType: null, payerAccount: null, transactionId: 13, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR | Debit: 67.81 EUR", date: new Date("2026-05-08T16:32:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIYA LIDL BALGARIYA EOOD UL TODOR", amount: 67.81, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 67.81, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 14, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: BGR SOFIA CBA EKO MARKET | Debit: 5.51 EUR", date: new Date("2026-05-07T06:02:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "BGR SOFIA CBA EKO MARKET", amount: 5.51, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.51, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 15, tags: { connect: [ { id: 1 } ] }, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
Row insert failed: Invalid `prisma.transactionImport.create()` invocation in /app/src/routes/upload.js:86:50 83 } 84 85 const transactionId = await linkTransaction(prisma, paymentData); → 86 const imp = await prisma.transactionImport.create({ data: { rawMessage: "Date: 08.05.2026 | Type: КАРТОВА ОПЕРАЦИЯ | Payee: POL BALICE Lagardere Travel R KR3 | Debit: 5.49 EUR", date: new Date("2026-05-06T10:16:00.000Z"), type: null, card: "400915xxxxxx4447", recipient: "POL BALICE Lagardere Travel R KR3", amount: 5.49, currency: "EUR", balance: null, source: "UPLOAD", debitBgn: 5.49, ~~~~~~~~ creditBgn: null, transactionType: "КАРТОВА ОПЕРАЦИЯ", payerAccount: null, transactionId: 16, ? status?: Status, ? debit?: Float | Null, ? credit?: Float | Null, ? createdAt?: DateTime, ? updatedAt?: DateTime, ? transaction?: TransactionCreateNestedOneWithoutImportsInput, ? tags?: TagCreateNestedManyWithoutTransactionImportsInput }, include: { tags: true } }) Unknown argument `debitBgn`. Did you mean `debit`? Available options are marked with ?.
View imported transactions
View imported transactions...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
23840
|
1003
|
38
|
2026-05-12T08:28:08.617363+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778574488617_m2.jpg...
|
Firefox
|
Jiminny — Work
|
True
|
app.jiminny.com/dashboard
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
New Tab
New Tab
Jy 20820 es reindex stream model h New Tab
New Tab
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Pull requests · jiminny/app
Pull requests · jiminny/app
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app
JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app
Data Explorer
Data Explorer
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
Jiminny
Jiminny
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
6
6
My Recordings
My Recordings
Team Recordings
Team Recordings
Everyone's Recordings
Everyone's Recordings
Unknown Customer
Sprint Review
29 Apr, 4:21 PM
Unknown Customer
Notetaker added by Adelina Petrova
24 Apr, 11:49 AM
Unknown Customer
Notetaker added by Adelina Petrova
23 Apr, 5:01 PM
Unknown Customer
2026-04-22-catch-up-on-setting-up-ai-score-cards (1)
Feedback Call
23 Apr, 4:06 PM
Unknown Customer
Notetaker added by Adelina Petrova
23 Apr, 1:12 PM
Unknown Customer
Userpilot Introduction 24.04.2026
23 Apr, 11:58 AM
Unknown Customer
2026-04-22-catch-up-on-setting-up-ai-score-cards
22 Apr, 4:15 PM
Emma Systems AS
test 2
Disco/Demo
21 Apr, 12:02 PM
Emma Systems AS
test 1
21 Apr, 11:49 AM
Unknown Customer
2026-04-16-call-to-447817433495
Disco/Demo
17 Apr, 10:45 AM
Unknown Customer
Sprint Review 15-04-2026
15 Apr, 5:39 PM
Unknown Customer
Notetaker added by Adelina Petrova
10 Mar, 1:42 PM
Unknown Customer
2024-10-03-notetaker-added-on-10-03-24-at-1524
Discovery
3 Oct, 2024, 5:37 PM
Schedule
Schedule
Invite Notetaker
This Week
This Week
My Schedule
My Schedule
Unknown Customer
Daily - Processing
Tomorrow, 10:10 AM
REC
Unknown Customer
Sprint Review
Tomorrow, 4:00 PM
REC
Unknown Customer
Retro - Processing
Tomorrow, 4:30 PM
REC
Unknown Customer
Planing - Processing
Thursday, 10:00 AM
REC
Unknown Customer
Daily - Processing
Thursday, 10:10 AM
REC
Unknown Customer
Daily - Processing
Friday, 10:10 AM
REC
Trending this month
Trending this month
Sort by Sort by: Most played
Sort by
Sort by:
Most played
Unknown Customer
Steve Lazarus and Greg Moser
Steve Lazarus and Greg Moser
4
times played
Semrush
Darko Petronijević and Petko Kashinski
Darko Petronijević and Petko Kashinski
4
times played...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.3643617,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"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.3776596,"top":0.06304868,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":4,"bounds":{"left":0.3643617,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app","depth":5,"bounds":{"left":0.3776596,"top":0.09577015,"width":0.16888298,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":4,"bounds":{"left":0.3643617,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira","depth":5,"bounds":{"left":0.3776596,"top":0.12849163,"width":0.16140293,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.3643617,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.3776596,"top":0.16121309,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.3643617,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.3776596,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.3643617,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.3776596,"top":0.22665602,"width":0.04537899,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":4,"bounds":{"left":0.3643617,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20773] User Pilot not receiving events on report generated - Jira","depth":5,"bounds":{"left":0.3776596,"top":0.25937748,"width":0.1200133,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":4,"bounds":{"left":0.3643617,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app","depth":5,"bounds":{"left":0.3776596,"top":0.29209897,"width":0.19331782,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20776] Automated report - sentry - Jira","depth":4,"bounds":{"left":0.3643617,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20776] Automated report - sentry - Jira","depth":5,"bounds":{"left":0.3776596,"top":0.32482043,"width":0.07646277,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":4,"bounds":{"left":0.3643617,"top":0.3463687,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"TypeError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app","depth":5,"bounds":{"left":0.3776596,"top":0.3575419,"width":0.40475398,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.3643617,"top":0.3790902,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.3776596,"top":0.39026338,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app","depth":4,"bounds":{"left":0.3643617,"top":0.41181165,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app","depth":5,"bounds":{"left":0.3776596,"top":0.42298484,"width":0.15159574,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Data Explorer","depth":4,"bounds":{"left":0.3643617,"top":0.4445331,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Data Explorer","depth":5,"bounds":{"left":0.3776596,"top":0.4557063,"width":0.0234375,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20776] Automated report - sentry - Jira","depth":4,"bounds":{"left":0.3643617,"top":0.4772546,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20776] Automated report - sentry - Jira","depth":5,"bounds":{"left":0.3776596,"top":0.4884278,"width":0.07646277,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.3643617,"top":0.509976,"width":0.07962101,"height":0.032721467},"on_screen":true,"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.3776596,"top":0.5211492,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.43168217,"top":0.5171588,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.3671875,"top":0.5442937,"width":0.07413564,"height":0.025538707},"on_screen":true,"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.3671875,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.37815824,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.38929522,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.40043217,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"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.41156915,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"6","depth":12,"bounds":{"left":0.44664228,"top":0.91380686,"width":0.015957447,"height":0.035115723},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"6","depth":14,"bounds":{"left":0.45611703,"top":0.9173983,"width":0.0023271276,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"My Recordings","depth":14,"bounds":{"left":0.48769948,"top":0.07182761,"width":0.039893616,"height":0.052673582},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"My Recordings","depth":15,"bounds":{"left":0.49035904,"top":0.0905826,"width":0.034574468,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Team Recordings","depth":14,"bounds":{"left":0.5275931,"top":0.07182761,"width":0.044714097,"height":0.052673582},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Team Recordings","depth":15,"bounds":{"left":0.53025264,"top":0.0905826,"width":0.03939495,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Everyone's Recordings","depth":14,"bounds":{"left":0.57230717,"top":0.07182761,"width":0.057679523,"height":0.052673582},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Everyone's Recordings","depth":15,"bounds":{"left":0.5749667,"top":0.0905826,"width":0.05236037,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":0.14684756,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sprint Review","depth":18,"bounds":{"left":0.49850398,"top":0.16640064,"width":0.026761968,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29 Apr, 4:21 PM","depth":17,"bounds":{"left":0.49850398,"top":0.1859537,"width":0.031083776,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":0.23423783,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Notetaker added by Adelina Petrova","depth":18,"bounds":{"left":0.49850398,"top":0.25379092,"width":0.069980055,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"24 Apr, 11:49 AM","depth":17,"bounds":{"left":0.49850398,"top":0.27334398,"width":0.033909574,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":0.3216281,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Notetaker added by Adelina Petrova","depth":18,"bounds":{"left":0.49850398,"top":0.34118116,"width":0.069980055,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23 Apr, 5:01 PM","depth":17,"bounds":{"left":0.49850398,"top":0.36073422,"width":0.031083776,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":0.40901837,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-22-catch-up-on-setting-up-ai-score-cards (1)","depth":17,"bounds":{"left":0.49850398,"top":0.42857143,"width":0.10488697,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Feedback Call","depth":17,"bounds":{"left":0.49850398,"top":0.4481245,"width":0.026928192,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23 Apr, 4:06 PM","depth":17,"bounds":{"left":0.49850398,"top":0.46767756,"width":0.031083776,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":0.5159617,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Notetaker added by Adelina Petrova","depth":18,"bounds":{"left":0.49850398,"top":0.5355148,"width":0.069980055,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23 Apr, 1:12 PM","depth":17,"bounds":{"left":0.49850398,"top":0.55506784,"width":0.031083776,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":0.60335195,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot Introduction 24.04.2026","depth":18,"bounds":{"left":0.49850398,"top":0.622905,"width":0.06648936,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23 Apr, 11:58 AM","depth":17,"bounds":{"left":0.49850398,"top":0.6424581,"width":0.033909574,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":0.6907422,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-22-catch-up-on-setting-up-ai-score-cards","depth":18,"bounds":{"left":0.49850398,"top":0.7102953,"width":0.0987367,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22 Apr, 4:15 PM","depth":17,"bounds":{"left":0.49850398,"top":0.7298484,"width":0.031083776,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Emma Systems AS","depth":17,"bounds":{"left":0.49850398,"top":0.7781325,"width":0.03507314,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"test 2","depth":17,"bounds":{"left":0.49850398,"top":0.79768556,"width":0.010970744,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Disco/Demo","depth":17,"bounds":{"left":0.49850398,"top":0.8172386,"width":0.024268618,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21 Apr, 12:02 PM","depth":17,"bounds":{"left":0.49850398,"top":0.8367917,"width":0.03357713,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Emma Systems AS","depth":17,"bounds":{"left":0.49850398,"top":0.8850758,"width":0.03507314,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"test 1","depth":18,"bounds":{"left":0.49850398,"top":0.9046289,"width":0.010970744,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21 Apr, 11:49 AM","depth":17,"bounds":{"left":0.49850398,"top":0.92418194,"width":0.033909574,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":0.9724661,"width":0.03873005,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-16-call-to-447817433495","depth":17,"bounds":{"left":0.49850398,"top":0.9920192,"width":0.06948138,"height":0.0079808235},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Disco/Demo","depth":17,"bounds":{"left":0.49850398,"top":1.0,"width":0.024268618,"height":-0.011572242},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17 Apr, 10:45 AM","depth":17,"bounds":{"left":0.49850398,"top":1.0,"width":0.033909574,"height":-0.031125307},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"bounds":{"left":0.49850398,"top":1.0,"width":0.03873005,"height":-0.07940936},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sprint Review 15-04-2026","depth":18,"bounds":{"left":0.49850398,"top":1.0,"width":0.05119681,"height":-0.098962545},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15 Apr, 5:39 PM","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Notetaker added by Adelina Petrova","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10 Mar, 1:42 PM","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2024-10-03-notetaker-added-on-10-03-24-at-1524","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Discovery","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 Oct, 2024, 5:37 PM","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Schedule","depth":13,"bounds":{"left":0.6491024,"top":0.25738227,"width":0.029421542,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Schedule","depth":14,"bounds":{"left":0.6491024,"top":0.25937748,"width":0.029421542,"height":0.021548284},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Invite Notetaker","depth":14,"bounds":{"left":0.7719415,"top":0.254988,"width":0.044215426,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"This Week","depth":14,"bounds":{"left":0.6540891,"top":0.3028731,"width":0.076961435,"height":0.02952913},"on_screen":true,"value":"This Week","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"This Week","depth":17,"bounds":{"left":0.657746,"top":0.31085396,"width":0.021775266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"My Schedule","depth":14,"bounds":{"left":0.734375,"top":0.3028731,"width":0.07679521,"height":0.02952913},"on_screen":true,"value":"My Schedule","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"My Schedule","depth":17,"bounds":{"left":0.7380319,"top":0.31085396,"width":0.02642952,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":16,"bounds":{"left":0.67569816,"top":0.36193135,"width":0.04155585,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Processing","depth":17,"bounds":{"left":0.67569816,"top":0.38268158,"width":0.036901597,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tomorrow, 10:10 AM","depth":16,"bounds":{"left":0.67569816,"top":0.40343177,"width":0.043882977,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"REC","depth":15,"bounds":{"left":0.77543217,"top":0.38028732,"width":0.013297873,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unknown Customer","depth":16,"bounds":{"left":0.67569816,"top":0.4481245,"width":0.04155585,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sprint Review","depth":17,"bounds":{"left":0.67569816,"top":0.4688747,"width":0.028756648,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tomorrow, 4:00 PM","depth":16,"bounds":{"left":0.67569816,"top":0.4896249,"width":0.04089096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"REC","depth":15,"bounds":{"left":0.77543217,"top":0.46648043,"width":0.013297873,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unknown Customer","depth":16,"bounds":{"left":0.67569816,"top":0.5343176,"width":0.04155585,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Retro - Processing","depth":17,"bounds":{"left":0.67569816,"top":0.55506784,"width":0.037898935,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tomorrow, 4:30 PM","depth":16,"bounds":{"left":0.67569816,"top":0.57581806,"width":0.04089096,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"REC","depth":15,"bounds":{"left":0.77543217,"top":0.5526736,"width":0.013297873,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unknown Customer","depth":16,"bounds":{"left":0.67569816,"top":0.62051076,"width":0.04155585,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Planing - Processing","depth":17,"bounds":{"left":0.67569816,"top":0.641261,"width":0.04155585,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Thursday, 10:00 AM","depth":16,"bounds":{"left":0.67569816,"top":0.66201115,"width":0.041722074,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"REC","depth":15,"bounds":{"left":0.77543217,"top":0.6388667,"width":0.013297873,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unknown Customer","depth":16,"bounds":{"left":0.67569816,"top":0.7067039,"width":0.04155585,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Processing","depth":17,"bounds":{"left":0.67569816,"top":0.7274541,"width":0.036901597,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Thursday, 10:10 AM","depth":16,"bounds":{"left":0.67569816,"top":0.7482043,"width":0.041722074,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"REC","depth":15,"bounds":{"left":0.77543217,"top":0.72505987,"width":0.013297873,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unknown Customer","depth":16,"bounds":{"left":0.67569816,"top":0.79289705,"width":0.04155585,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Processing","depth":17,"bounds":{"left":0.67569816,"top":0.8136473,"width":0.036901597,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Friday, 10:10 AM","depth":16,"bounds":{"left":0.67569816,"top":0.83439744,"width":0.035405584,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"REC","depth":15,"bounds":{"left":0.77543217,"top":0.811253,"width":0.013297873,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Trending this month","depth":13,"bounds":{"left":0.6540891,"top":0.08858739,"width":0.046210106,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Trending this month","depth":14,"bounds":{"left":0.6540891,"top":0.0905826,"width":0.046210106,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Sort by Sort by: Most played","depth":13,"bounds":{"left":0.74268615,"top":0.08339984,"width":0.068484046,"height":0.02952913},"on_screen":true,"value":"Sort by Sort by: Most played","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,"on_screen":false,"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.7463431,"top":0.091380686,"width":0.016954787,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Most played","depth":15,"bounds":{"left":0.76329786,"top":0.091380686,"width":0.025930852,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unknown Customer","depth":16,"bounds":{"left":0.7077792,"top":0.16719872,"width":0.043218084,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Steve Lazarus and Greg Moser","depth":15,"bounds":{"left":0.695645,"top":0.18555467,"width":0.07396942,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Steve Lazarus and Greg Moser","depth":16,"bounds":{"left":0.7056183,"top":0.18555467,"width":0.054022606,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":16,"bounds":{"left":0.7340425,"top":0.20151636,"width":0.0043218085,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"times played","depth":17,"bounds":{"left":0.7234042,"top":0.21628092,"width":0.01861702,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Semrush","depth":16,"bounds":{"left":0.8869681,"top":0.16719872,"width":0.019281914,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Darko Petronijević and Petko Kashinski","depth":15,"bounds":{"left":0.85488695,"top":0.18555467,"width":0.08992686,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Darko Petronijević and Petko Kashinski","depth":16,"bounds":{"left":0.86486036,"top":0.18555467,"width":0.069980055,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4","depth":16,"bounds":{"left":0.9012633,"top":0.20151636,"width":0.0043218085,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"times played","depth":17,"bounds":{"left":0.890625,"top":0.21628092,"width":0.01861702,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9081910726791814001
|
-7033186163074794840
|
click
|
accessibility
|
NULL
|
New Tab
New Tab
Jy 20820 es reindex stream model h New Tab
New Tab
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
Jy 20820 es reindex stream model hydration by Vasil-Jiminny · Pull Request #12059 · jiminny/app
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
[JY-20725] [HubSpot] Optimise CRM rematching on delete hubspot accounts/contacts - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Pull requests · jiminny/app
Pull requests · jiminny/app
[JY-20773] User Pilot not receiving events on report generated - Jira
[JY-20773] User Pilot not receiving events on report generated - Jira
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
JY-20773 fix user pilot tracking ofr automated report generated by LakyLak · Pull Request #12024 · jiminny/app
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
TypeError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line 218 — jiminny — app
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app
JY-20625 | JY-20742 | MCP POC by yalokin-jiminny · Pull Request #12036 · jiminny/app
Data Explorer
Data Explorer
[JY-20776] Automated report - sentry - Jira
[JY-20776] Automated report - sentry - Jira
Jiminny
Jiminny
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
6
6
My Recordings
My Recordings
Team Recordings
Team Recordings
Everyone's Recordings
Everyone's Recordings
Unknown Customer
Sprint Review
29 Apr, 4:21 PM
Unknown Customer
Notetaker added by Adelina Petrova
24 Apr, 11:49 AM
Unknown Customer
Notetaker added by Adelina Petrova
23 Apr, 5:01 PM
Unknown Customer
2026-04-22-catch-up-on-setting-up-ai-score-cards (1)
Feedback Call
23 Apr, 4:06 PM
Unknown Customer
Notetaker added by Adelina Petrova
23 Apr, 1:12 PM
Unknown Customer
Userpilot Introduction 24.04.2026
23 Apr, 11:58 AM
Unknown Customer
2026-04-22-catch-up-on-setting-up-ai-score-cards
22 Apr, 4:15 PM
Emma Systems AS
test 2
Disco/Demo
21 Apr, 12:02 PM
Emma Systems AS
test 1
21 Apr, 11:49 AM
Unknown Customer
2026-04-16-call-to-447817433495
Disco/Demo
17 Apr, 10:45 AM
Unknown Customer
Sprint Review 15-04-2026
15 Apr, 5:39 PM
Unknown Customer
Notetaker added by Adelina Petrova
10 Mar, 1:42 PM
Unknown Customer
2024-10-03-notetaker-added-on-10-03-24-at-1524
Discovery
3 Oct, 2024, 5:37 PM
Schedule
Schedule
Invite Notetaker
This Week
This Week
My Schedule
My Schedule
Unknown Customer
Daily - Processing
Tomorrow, 10:10 AM
REC
Unknown Customer
Sprint Review
Tomorrow, 4:00 PM
REC
Unknown Customer
Retro - Processing
Tomorrow, 4:30 PM
REC
Unknown Customer
Planing - Processing
Thursday, 10:00 AM
REC
Unknown Customer
Daily - Processing
Thursday, 10:10 AM
REC
Unknown Customer
Daily - Processing
Friday, 10:10 AM
REC
Trending this month
Trending this month
Sort by Sort by: Most played
Sort by
Sort by:
Most played
Unknown Customer
Steve Lazarus and Greg Moser
Steve Lazarus and Greg Moser
4
times played
Semrush
Darko Petronijević and Petko Kashinski
Darko Petronijević and Petko Kashinski
4
times played...
|
23838
|
NULL
|
NULL
|
NULL
|
|
16942
|
757
|
16
|
2026-05-11T09:43:58.733656+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778492638733_m2.jpg...
|
Control Centre
|
Control Centre
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Bluetooth
Bluetooth
Devices
Lukas’s Magic Mouse, 4 Bluetooth
Bluetooth
Devices
Lukas’s Magic Mouse, 48%
soundcore AeroClip
LakyLak bose qc35 II
M720 Triathlon
Magic Keyboard
Magic Keyboard
Soundcore Life Dot 2 NC
Bluetooth Settings…...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Bluetooth","depth":2,"bounds":{"left":0.6492686,"top":1.0,"width":0.02044548,"height":-0.034317613},"on_screen":true,"automation_id":"bluetooth-header","role_description":"text"},{"role":"AXCheckBox","text":"Bluetooth","depth":2,"bounds":{"left":0.72639626,"top":1.0,"width":0.012632979,"height":-0.031923413},"on_screen":true,"automation_id":"bluetooth-header","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false},{"role":"AXHeading","text":"Devices","depth":3,"bounds":{"left":0.6492686,"top":1.0,"width":0.015458777,"height":-0.065043926},"on_screen":true,"role_description":"heading"},{"role":"AXCheckBox","text":"Lukas’s Magic Mouse, 48%","depth":3,"bounds":{"left":0.6462766,"top":1.0,"width":0.095744684,"height":-0.07980847},"on_screen":true,"automation_id":"bluetooth-device-Lukas’s Magic Mouse","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"soundcore AeroClip","depth":3,"on_screen":true,"automation_id":"bluetooth-device-soundcore AeroClip","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"LakyLak bose qc35 II","depth":3,"on_screen":true,"automation_id":"bluetooth-device-LakyLak bose qc35 II","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"M720 Triathlon","depth":3,"on_screen":true,"automation_id":"bluetooth-device-M720 Triathlon","role_description":"toggle button","subrole":"AXToggle","is_enabled":false},{"role":"AXCheckBox","text":"Magic Keyboard","depth":3,"on_screen":true,"automation_id":"bluetooth-device-Magic Keyboard","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"Magic Keyboard","depth":3,"on_screen":true,"automation_id":"bluetooth-device-Magic Keyboard","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"Soundcore Life Dot 2 NC","depth":3,"on_screen":true,"automation_id":"bluetooth-device-Soundcore Life Dot 2 NC","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXButton","text":"Bluetooth Settings…","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false}]...
|
-9079547231437546489
|
-7776680772692915260
|
visual_change
|
hybrid
|
NULL
|
Bluetooth
Bluetooth
Devices
Lukas’s Magic Mouse, 4 Bluetooth
Bluetooth
Devices
Lukas’s Magic Mouse, 48%
soundcore AeroClip
LakyLak bose qc35 II
M720 Triathlon
Magic Keyboard
Magic Keyboard
Soundcore Life Dot 2 NC
Bluetooth Settings…
Proiect v100% 5• мon 11 May 12.43.00+0 ..(C) DeleteAccount loh 1lC DelerecontactJob.u velerecrmenutyiraC DeleteleaaJoo.onpc Deleteopportunityc VerivAcuvityermi>@ Hubspot> C Salesforce(c) AutoloaDelavedToermC) CheckAndRetrvRemotC) CreateFollowupActivitc) CreateNotes.oho© MatchActivitiesToNew 109© MatchActivitvCrmData 110(E) [EMAIL]) SaveActivitv.oho© SaveTranscriotion.ohn 113C) Setuolavout.oho© SyncActivity.php© SyncFieldMetadata.ph 110© SyncHubspotObiects.r 117© SyncLeads.php© SyncObjects.php© SyncOpportunitiesJob. 12€© SyncOpportunity.php© SyncProfileMetadata.p 122© SyncTeamFieldsJob.pl 123© SyncTeamMetadata.pl 124c Uodarevooonuniysotc) Updatestage.pho> C DealRisksMallbox_ MeetinaBot_ Middleware© HandleHubspotRateLir 131C) RateLimited.ohoM StreaminaTeamTelephonv135MUserc) chandeSmaillob.ohr@ Deactivatelser.lob.nh 138(C) DeleteScheduledUserl 159(C) SetunDefaultSavedSe: 140C) SvncTolntercom.nhn(C) SvncToPlanhat.nhn© SyncToUserPilot.php© BaseProcessingJob.php(C) Nummy loh nhn© ImportRecallAlRecordings 152© ImportRemoteTrackJob.p 153RematchActivityOnCrmObiectDetach.pnpermactivityservice.ongRateLimitException.phpC) MatchCrmData.php(C) HandleHubspotRateLimit.phpC) CrmObiectsResolver.phoclass VerifyActivityCrmTaskJob extends Job implements ShouldQueueoublicfunction handled'activity' => Sactivity->getId.'erm nroviden id' => Sactivitv->aetCrmProvidenTdol'crm_provider' => $providerName1):Sactivity->update(['crm_provider_id' => null]):} else {Slogger->info('[VerifyActivityCrmTask] CRM task verified successfully'. [→ saculvity-oeclo'crm_provider id' => Sactivity->qetCrmProviderIdocrm provider' = Sprovidername.} catch (SocialAccountTokenInvalidException Sexception) {Urmuwnerkesolver couldn't tind anv user wirh active uri connectionIl This is a permanent error - no point retryingSlogger->warnina('|VerifvActivitvcrmlask Noactive CRM connection found'. ['activitv' => Sactivity->aetIdol=> Steam->cetido.excention' = sexcention->aetMessadeolcatch Throwable Sexcention) ^// Transient errors (network issues, rate limits, API timeouts, etc.)// These are worth retrying - let the job retry mechanism handle them$logger->error('[VerifyActivityCrmTask) Error verifying CRM task', ['crm_provider_id' => $activity->getCrmProviderId.'exception' => $exception->getMessageO'exception class' =› get class(Sexception).chrow sexception;public function failed(Throwable Sexception): voidf...}A2 X10 ^A SF (jiminny@localhost]4 HS_local (jiminny@localhost]# console [PKob.# console [euJ# console [slAGiNg)[2026-05-07 14:21:15] local.INF0: [Hubspot] DEBUG Getting headers {"neaders".?"Uace":L"Inu,or May 2020 14.21.15 6Ml"Jn"Transter-Encod1nq":"chunked")."Connection":"keep-alive""CF-Ray":L"9t80debödb60dcsa-S0F"J,"Strict-Transport-Secur1ty":"max-aqe=31536008* 1ncLudeSubDomains: preload")naccent-encodino""access-control-allow-credentials": ["false"J."server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\","x-content-tvoe-ootions":"nosniff"]"x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],"So+-Cookie"." c+hm-Stlirtd0aXVr.kSandas6hzVVKhzTn0BidvMaheCtmoV-1778163675-1.0.107-May-26 14:51:15 GMT; domain=.hubapi.com; Http0nly; Secure; SameSite=None"],"Report-To":["{"endpoints\":[{"unl".httns:la.nel.cloudflane.com./renon+W/v42c=NVA1cVTPQfVm32anS0#xVF/sd2RN"group\":\"cf-nel\","max_age\":604800}"],"NEL": ["1\"success_fraction\":0.01,reportto. "cr-nel,"max age":604800}"]"Server": ["cloudflare"]}} {"correlation_ 1d":"95256555-ec98-4541-b9za-adta/Sboyeab","trace_10":C/AD8565-905t-4604-9405-0e5b551e5545Cascade0 HubSpot Rate Limiif emotv(SactivitvIdsWithCrmId))foreach (array_chunk($activityIdsWithCrmId, 100) as $chunk) {VeritvActivitiescrnlasks.o0::disoatchSchunk)Combined with HubSpot's batch read endpoint ( POST /crm/v3/objects/tasks/batch/read ), 100 verifications = 1 APl call. 100x throughput improvement on theverity pathEftort medium new bulk iob class + batch read imolementation. Imbact: 100xOntion 3: Move the cascade out of the transactioncurrently the trait dispatches VerifyActivityCrmTaskJob inside the parent's Sdb→>transaction... block (see DeleteContactjob.php:54-91 ). Two issues:• If the transaction rolls back, the verify jobs are already in the queue (Redis is not transactional with MySQL). They'll attempt to verify activities whose deletionwas rolled back. Wasted work.•The transaction holds locks while we enumerate and dispatch potentially thousands of jobs. Lock duration scales with activity countix: collect Ids durind the transaction. dispatch after commit.• phpprotected function handleActavitzes(...) : arrayif (Sactivities->isEmpty)) ‹utenlorry-Sactivities-›each(function (Activity Sactivitv) use (.... &SidsToVerifv): void &••• existing update Logzeit Sactivitv->hasCrmProviderIdoSidsToVerifvil = Sactivitv-aettdd.return SidstoVerity:Thon in DolotoContactlohe«handlor• phpcideTolorsfy e fl.Sdb->transaction(function () use (.... &SidsToVerifv): void..•all cleanup ...SidstoVerifv = Sthis->handleActivities(Sactivities, Sdispatcher. Slogger):// Dispatch AFTER commitforeach ($idsToVerify as $id) {VerifvActivitvCrmTaskJob::dispatch(Sid):Effort: small. Impact: correctness (no orohan verifv iobs from rolled-back transactions) + shorter transactions.Ask anvthing (84D)+ « CodeClaude Onus 4.7 Mediumfo 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
16943
|
756
|
17
|
2026-05-11T09:44:16.971128+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778492656971_m1.jpg...
|
Control Centre
|
Control Centre
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Bluetooth
Bluetooth
Devices
Lukas’s Magic Mouse, 4 Bluetooth
Bluetooth
Devices
Lukas’s Magic Mouse, 48%
soundcore AeroClip
LakyLak bose qc35 II
M720 Triathlon
Magic Keyboard
Magic Keyboard
Soundcore Life Dot 2 NC
Bluetooth Settings…...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Bluetooth","depth":2,"bounds":{"left":0.7916667,"top":0.04777778,"width":0.042708334,"height":0.017777778},"on_screen":true,"automation_id":"bluetooth-header","role_description":"text"},{"role":"AXCheckBox","text":"Bluetooth","depth":2,"bounds":{"left":0.9527778,"top":0.044444446,"width":0.02638889,"height":0.024444444},"on_screen":true,"automation_id":"bluetooth-header","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false},{"role":"AXHeading","text":"Devices","depth":3,"bounds":{"left":0.7916667,"top":0.090555556,"width":0.032291666,"height":0.016666668},"on_screen":true,"role_description":"heading"},{"role":"AXCheckBox","text":"Lukas’s Magic Mouse, 48%","depth":3,"bounds":{"left":0.78541666,"top":0.11111111,"width":0.2,"height":0.035555556},"on_screen":true,"automation_id":"bluetooth-device-Lukas’s Magic Mouse","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"soundcore AeroClip","depth":3,"bounds":{"left":0.78541666,"top":0.14666666,"width":0.2,"height":0.035555556},"on_screen":true,"automation_id":"bluetooth-device-soundcore AeroClip","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"LakyLak bose qc35 II","depth":3,"bounds":{"left":0.78541666,"top":0.18222222,"width":0.2,"height":0.035555556},"on_screen":true,"automation_id":"bluetooth-device-LakyLak bose qc35 II","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"M720 Triathlon","depth":3,"bounds":{"left":0.78541666,"top":0.21777777,"width":0.2,"height":0.035555556},"on_screen":true,"automation_id":"bluetooth-device-M720 Triathlon","role_description":"toggle button","subrole":"AXToggle","is_enabled":false},{"role":"AXCheckBox","text":"Magic Keyboard","depth":3,"bounds":{"left":0.78541666,"top":0.25333333,"width":0.2,"height":0.035555556},"on_screen":true,"automation_id":"bluetooth-device-Magic Keyboard","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"Magic Keyboard","depth":3,"bounds":{"left":0.78541666,"top":0.2888889,"width":0.2,"height":0.035555556},"on_screen":true,"automation_id":"bluetooth-device-Magic Keyboard","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"Soundcore Life Dot 2 NC","depth":3,"bounds":{"left":0.78541666,"top":0.32444444,"width":0.2,"height":0.035555556},"on_screen":true,"automation_id":"bluetooth-device-Soundcore Life Dot 2 NC","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXButton","text":"Bluetooth Settings…","depth":2,"bounds":{"left":0.78541666,"top":0.37555555,"width":0.09791667,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false}]...
|
-9079547231437546489
|
-7776680772692915260
|
idle
|
hybrid
|
NULL
|
Bluetooth
Bluetooth
Devices
Lukas’s Magic Mouse, 4 Bluetooth
Bluetooth
Devices
Lukas’s Magic Mouse, 48%
soundcore AeroClip
LakyLak bose qc35 II
M720 Triathlon
Magic Keyboard
Magic Keyboard
Soundcore Life Dot 2 NC
Bluetooth Settings…
Finder•FileEditViewGoWindowHelpDEV (docker)DOCKER₴1DEV (docker)882XIAPP (-zsh)|masterJY-20818-move-AJ-reports-to-separated-datadog-metricJY-20773-fix-automated-reports-user-pilot-trackingJY-20157-AJ-report-not-send-notificationJY-20508-notify-before-AJ-report-expirationJY-20372-ai-reports-promotion-pagesJY-20352-sync-opportunities-without-a-local-owner-user-id-is-nullJY-20738-debug-AJ-tracking-UPJY-18909-automated-reports-ask-jiminnyJY-20692-fix-integration-app-[API_KEY]@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ devroot@docker_lamp_1:/home/jiminny# ]abl§ Support Daily - in 2h 16 m-zsh-zsh100% C8•Mon 11 May 12:44:16BluetoothDevicesLukas's Magic Mousesoundcore AeroClipLakyLak bose qc35 llM720 TriathlonMagic KeyboardMagic Keyboard48% •Soundcore Life Dot 2 NCBluetooth Settings......
|
NULL
|
NULL
|
NULL
|
NULL
|
|
2034
|
96
|
10
|
2026-05-07T10:56:47.916384+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778151407916_m2.jpg...
|
Claude
|
Claude
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Skip to content
Skip to content
Click to collapse
Skip to content
Skip to content
Click to collapse
⌘B
Drag to resize
Open sidebar
Chat
Cowork
Code
New chat ⌘N
New chat
⌘N
Projects
Artifacts
Customize
Pinned
Bulgarian citizenship application process for EU residents
More options for Bulgarian citizenship application process for EU residents
Dawarich location tracking project
More options for Dawarich location tracking project
Recents
View all
HubSpot rate limit implementation strategy
More options for HubSpot rate limit implementation strategy
Screenpipe retention policy code location
More options for Screenpipe retention policy code location
Viewing retention policy in screenpipe
More options for Viewing retention policy in screenpipe
Clean shot x video recording termination issue
More options for Clean shot x video recording termination issue
HubSpot rate limit handling with executeRequest
More options for HubSpot rate limit handling with executeRequest
Untitled
More options
💬 Screen pipe. Is there ability…
More options for 💬 Screen pipe. Is there ability…
SMB mount access inconsistency between Finder and iTerm
More options for SMB mount access inconsistency between Finder and iTerm
💬 What is the best switch I can…
More options for 💬 What is the best switch I can…
Permission denied on screenpipe volume
More options for Permission denied on screenpipe volume
Screenpipe sync database attachment error
More options for Screenpipe sync database attachment error
Last swimming outing with Dani
More options for Last swimming outing with Dani
Definition of incarcerated
More options for Definition of incarcerated
Chromecast remote volume buttons not working
More options for Chromecast remote volume buttons not working
Salesforce API errors with Organization and FieldDefinition queries
More options for Salesforce API errors with Organization and FieldDefinition queries
Daily activity summary from screenpipe data
More options for Daily activity summary from screenpipe data
MacBook unexpected restarts and kanji screen
More options for MacBook unexpected restarts and kanji screen
Security patch review and testing guidance
More options for Security patch review and testing guidance
Food calorie values reference
More options for Food calorie values reference
Tracking location history from last week
More options for Tracking location history from last week
Lukas Pro
Get apps and extensions
HubSpot rate limit implementation strategy, rename chat
HubSpot rate limit implementation strategy
More options for HubSpot rate limit implementation strategy
Share chat
Claude finished the response
You said: So just a solution for rate limit implementation.
You said: So just a solution for rate limit implementation.
So just a solution for rate limit implementation. The situation currently is that there are some daily and secondary limits for HubSpot. I would like to make sure I never reach a 429 error rate limit. The requests can come from any flow. It can be:
updating activity (engagement, meeting, call, note)
searching for a company or contact
updating deal
patching IDs
Review what the limit is at the moment in the HubSpot documentation and then think of the solution:
where to store it
how to read it
how to work with multiple jobs
how to work with paginated requests Let's consider a situation when there are 600 opportunities to sync. What would be the flow? How would the rate limit be recognized? How would it be handled? What are the potential issues? [API usage guidelines and limits - HubSpot docs](
https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines
https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines
). Example of such a error Client error:
POST https://api.hubapi.com/crm/v3/objects/contact/search
resulted in a
429 Too Many Requests
response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT","correlationId":"019dffc4-4 (truncated...). Think carefully about the implementation and potential issue and bottlenecks.
Show more
10:42
Retry
Edit
Copy
Claude responded: Current HubSpot limits (Apr 2026)
Claude responded: Current HubSpot limits (Apr 2026)
Synthesized HubSpot rate limit architecture with Redis storage and sliding window algorithms
Synthesized HubSpot rate limit architecture with Redis storage and sliding window algorithms
Current HubSpot limits (Apr 2026)
Current HubSpot limits (Apr 2026)
For privately distributed apps (which is what Jiminny presumably uses with HubSpot), the limits are layered: a per-app burst window of 100/10s on Free/Starter, 190/10s on Pro/Enterprise, or 250/10s with the API Limit Increase add-on
, plus a per-account daily cap of 250k / 625k / 1M depending on tier — shared across all private apps in the account
. The burst window is per app; the daily quota is per portal.
hubspot
hubspot
hubspot
hubspot
The Search API is special: five requests per second per account, capped at 200 records per page, with a hard 10,000-result ceiling per query
. That's the limit the 429 in your example is hitting (
secondly limit
on
/crm/v3/objects/contact/search
). It's a separate bucket from the 190/10s, and critically, search responses do not include the
X-HubSpot-RateLimit-*
headers
— you can't read remaining capacity off the response, you have to track it yourself.
hubspot
hubspot
hubspot
hubspot
Non-search endpoints return
X-HubSpot-RateLimit-Remaining
,
-Max
, and
-Interval-Milliseconds
. The daily headers are not returned for OAuth-authenticated calls
, so for those you check the account-info endpoint or maintain your own counter. There's also a soft rule: errors should stay under 5% of total daily requests
— that's enforced for marketplace listing, but it's also a sane operational target.
hubspot
hubspot
hubspot
hubspot
So you have
four buckets
to track at minimum: app-burst (10s sliding), search-secondly (1s sliding), account-daily (24h fixed, midnight in HubSpot's TZ), and per-app daily share (your own budgeting on top of the account cap).
Where to store it
Where to store it
Redis. It's the only realistic option once you have multiple queue workers — DB-backed counters serialize too much, and in-process state can't coordinate across workers. Laravel already speaks Redis natively, and you get atomic
INCR
/
EXPIRE
plus Lua scripting for true CAS semantics.
Key layout I'd use:
Copy to clipboard
hubspot:rl:burst:{portalId}:{appId} ZSET (sliding 10s)
hubspot:rl:search:{portalId} ZSET (sliding 1s)
hubspot:rl:daily:{portalId} STRING + TTL to midnight TZ
hubspot:rl:meta:{portalId} HASH (last seen headers)
The two short-window buckets are sliding-window-log (Redis ZSET, score =
microtime
, member = unique request id). Lua script removes entries older than the window, counts remaining slots, and only adds the new one if there's room — all atomic. Fixed windows are simpler but allow 2× the limit at the boundary, which on a 5/s window is brutal.
The daily bucket is a plain
INCR
with TTL set to seconds-until-midnight in
HubSpot's account timezone
, not yours — Sofia is UTC+2/+3 but your portal might be set to US Eastern. Get this once and cache it.
How to read it
How to read it
Two-phase: optimistic pre-check, authoritative post-update.
Before a call, run the Lua acquire script. If it returns "denied," sleep until a slot frees up (the script can return ms-until-next-slot) or push the job back to the queue with a delay. Don't busy-loop.
After the call, parse
X-HubSpot-RateLimit-Remaining
/
-Max
/
-Interval-Milliseconds
and store them in
hubspot:rl:meta:{portalId}
. This is your reality check — if your local counter says 50 remaining but HubSpot's header says 5, you trust HubSpot and clamp your counter. This handles clock drift, missed accounting (e.g., crashed worker that took a token but never made the request), and other apps in the same account consuming the daily budget invisibly.
For search specifically, since headers don't come back, the local counter
is
the source of truth — meaning if you ever crash mid-flight, you've under-counted. Always release tokens on connection-level failure but
not
on 429 (you really did make that request).
How to work with multiple jobs
How to work with multiple jobs
The queue layer needs to enforce concurrency separately from the rate limiter. Both work together:
Concurrency cap
via
Queue::throttle()
or a Redis semaphore — limits how many sync workers run in parallel against HubSpot. Without this, you can have 50 workers all blocked waiting for tokens, which is wasteful and creates retry storms.
Per-tenant fairness
— if you sync many Jiminny customers into different HubSpot portals, each portal has its own bucket but you still want one slow portal not to starve others. Either separate queues per portal or a fair-share scheduler.
Priority lanes
— webhook-driven updates (user-visible latency) should outrank background batch syncs. Two queues:
hubspot-priority
and
hubspot-bulk
, with priority workers taking 70% of the burst budget and bulk taking 30% (enforce via separate sub-buckets if you really want hard separation, otherwise just pull from priority first).
Backoff on 429
— respect the
Retry-After
header. If absent, exponential with jitter (e.g.,
min(2^attempt * 250ms, 30s) ± 20%
). The jitter is non-negotiable; without it, simultaneous 429s retry in lockstep and you get thundering-herd 429s on retry.
How to work with paginated requests
How to work with paginated requests
The trap is treating "fetch all" as one logical operation. Each page is its own API call and competes for tokens with everything else.
Two practical rules:
Don't hold the worker idle while paginating.
If page N takes 500ms and page N+1 needs to wait 800ms for a token, you've burned 800ms of worker time doing nothing. Instead, fetch page N, dispatch the
processing
of page N as a separate job, and queue a "fetch page N+1" job with a delay equal to the wait time. Each page becomes its own atomic unit.
Always batch where HubSpot offers it.
POST /crm/v3/objects/{type}/batch/{read|update|create}
accepts up to 100 IDs per call. For your "patching IDs" flow this is the difference between 600 calls and 6.
Walkthrough: 600 opportunities
Walkthrough: 600 opportunities
Naive flow (one PATCH per deal): 600 calls. At 190/10s that's ~32s of API time, well under daily. You'd hit burst easily without throttling. Plus likely 1-3 search calls upfront and N association calls.
Sane flow:
Identify deltas
— if you can avoid Search at all, do. Use
lastmodifieddate
filter on a single search if you must, paginate at limit=200. For 600 deals that's 3 search calls @ 5/s = ~600ms naturally throttled.
Batch read
current state —
POST /crm/v3/objects/deals/batch/read
with 100 IDs per call → 6 calls. Burst weight 6.
Compute diff
in your code (no API).
Batch update
—
POST /crm/v3/objects/deals/batch/update
with 100 per call → 6 calls.
Associations
—
POST /crm/v4/associations/{from}/{to}/batch/create
if needed → another few batch calls.
Total: ~15-20 API calls for 600 deals. Burst budget consumed: 20/190 over ~5s. Daily impact: trivial.
Recognition: pre-check denies if
<weight>
slots aren't free; on 429 the response surfaces
policyName
(DAILY/SECONDLY) — log it, push the job back with
Retry-After
delay, increment a metric so you can alarm on sustained 429 rate.
Pitfalls & bottlenecks worth pre-empting
Pitfalls & bottlenecks worth pre-empting
Daily quota is shared across the whole portal
, including any n8n flows, other private apps, marketing automation calling APIs, etc. Budget for ~70-80% of the documented limit, not 100%. Add an internal per-app daily cap so a runaway sync can't starve other apps.
Search is uniquely fragile
: separate 5/s bucket, no headers to read, 10k-result cap per query. If you ever hit 10k+ deals matching a filter, partition by
hs_object_id
ranges or by
lastmodifieddate
windows.
Retry storms after HubSpot incidents
— always jitter, always cap total retries (e.g., 5 attempts, then dead-letter).
Webhook → sync → webhook loops
— when your update fires a HubSpot webhook that triggers another sync. Tag your own writes (e.g., a custom property
jy_last_sync_id
) and ignore webhooks where it just changed.
Token refresh
— OAuth refresh itself counts against burst. Cache the access token in Redis with TTL =
expires_in - 60s
, single-flight the refresh (only one worker refreshes; others wait on a lock).
Search latency for fresh writes
— newly created/updated objects don't appear in search instantly. Don't write-then-search; use returned IDs directly.
Clock skew
— Redis is authoritative. Don't use
time()
from each worker for window scoring; use
redis.call('TIME')
inside the Lua script.
Dead workers with held tokens
— sliding-window-log handles this naturally because tokens expire by score; token-bucket implementations need explicit release-on-crash logic.
The 5% error rule
counts every 429 toward your error budget, even successfully retried ones. If your pre-check is working well, 429s should be near zero — if they're not, your pre-check is wrong, not just slow.
Phantom contention with Laravel
RateLimited
middleware
: it's per-job-class by default, not per-portal. If your
SyncDealJob
and
UpdateActivityJob
are different classes both calling HubSpot, they don't share a Laravel-level limiter — you need a single
HubspotRateLimiter
service that everything routes through.
If you want, I can sketch the Lua script for the sliding-window acquire and the Laravel service wrapper around it.
Copy
Give positive feedback
Give negative feedback
Retry
You said: What will happen if there are two different types of rate limits?
You said: What will happen if there are two different types of rate limits?
What will happen if there are two different types of rate limits?
Search requests that have 5 requests per second
The other rate limit that has, let's say, 100 requests per 10 seconds How do these work together? Is there some conflict? Can I reach the limit with one request and block either as well, or are these separated? Can I still continue making search requests once I hit the normal requests limits?
13:40
Retry
Edit
Copy
Claude responded: They're independent buckets — with one shared bucket on top.
Claude responded: They're independent buckets — with one shared bucket on top.
Analyzed independent rate limit buckets and their practical interactions
Analyzed independent rate limit buckets and their practical interactions
They're independent buckets — with one shared bucket on top.
The three buckets and what each call hits
The three buckets and what each call hits
Copy to clipboard
┌──────────────────┐
Search request ──→ │ Search: 5/sec │ ──┐
└──────────────────┘ │
├──→ ┌─────────────────┐
┌──────────────────┐ │ │ Daily: 250k–1M │
Non-search call ──→ │ Burst: 190/10s │ ──┘ │ (per portal) │
└──────────────────┘ └─────────────────┘
A search call is only metered against the search bucket and the daily bucket. A non-search call (batch read/update, single PATCH, associations, etc.) is only metered against the burst bucket and the daily bucket. The two short-window buckets do not share counters.
What this means practically
What this means practically
Hitting search secondly limit (5/s):
Only further
/search
calls 429. Your batch reads, batch updates, single PATCHes, association calls — all keep working at full burst speed. This is actually useful: if your sync is bottlenecked on Search, you can pivot to using
lastmodifieddate
filters via batch endpoints, or use the IDs you already have to do batch reads, while Search cools off.
Hitting burst limit (190/10s):
Only non-search calls 429. You can still issue Search calls at 5/s. Useful for: continuing to identify deltas for queueing while in-flight updates drain, or refreshing a small set of records via Search even though your write pipeline is paused.
Hitting daily limit:
Everything stops. Search and non-search alike. Doesn't unblock until midnight in your portal's configured timezone — and remember this is shared across every private app in the portal, plus n8n flows, marketing tools, anything else hitting the API with that account.
So can one type of request block the other?
So can one type of request block the other?
Search → Burst:
No.
Saturating Search at 50 calls per 10s leaves your full 190/10s burst untouched.
Burst → Search:
No.
Saturating burst leaves Search's 5/s untouched.
Either → Daily:
Yes
, but only by contributing to the same daily counter. It's volume that kills you here, not the type.
In theory you can sustain ~50 search + ~190 other =
~240 calls per 10 seconds
indefinitely (until daily runs out), because the two buckets bill independently.
Implementation consequence
Implementation consequence
Your rate limiter needs to know which bucket a request hits before it acquires. Cleanest pattern:
Copy to clipboard
php
$limiter
->
acquire
(
'search'
,
$weight
=
1
)
;
// for search endpoints only
$limiter
->
acquire
(
'burst'
,
$weight
=
1
)
;
// for everything else
$limiter
->
acquire
(
'daily'
,
$weight
=
1
)
;
// every call, both kinds
In Redis: three separate keys, three separate Lua acquire scripts (or one script with a bucket parameter). A search call calls
acquire('search')
+
acquire('daily')
. A batch update calls
acquire('burst')
+
acquire('daily')
.
One subtle pitfall: when you backoff on a 429,
inspect
policyName
in the response body
to know which bucket actually fired. If you see
SECONDLY
from a search endpoint, you only need to delay search-bound jobs — burst-bound jobs in the queue can keep running. If you blanket-pause everything on any 429, you waste capacity on the bucket that's still healthy. Two queues (or two throttle keys) make this clean; one global pause is the lazy version.
The other subtlety: the burst response gives you
X-HubSpot-RateLimit-Remaining
to clamp local state against, but search doesn't return those headers. So your search counter is unverified — be slightly more conservative there (e.g., budget 4/s instead of 5) to absorb the unaccounted-for calls.
Copy
Give positive feedback
Give negative feedback
Retry
You said: Ok, so what will happen each time I make a request?
You said: Ok, so what will happen each time I make a request?
Ok, so what will happen each time I make a request? Let's say I have 100,000 requests to make that are instant. Do I need to increment each request based on the type? For example, if there is a search request, I need to increment both the search bucket and also the daily bucket. If it's a burst, then I can go to the daily and burst buckets. If I need to check if it can make a call, do I need to see both the daily and search, or burst, respectively? Isn't that too heavy for the infrastructure, adding additional load to each request?
13:44
Retry
Edit
Copy
Claude responded: Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out.
Claude responded: Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out.
Analyzed per-request overhead concerns and quantified Redis performance impact
Analyzed per-request overhead concerns and quantified Redis performance impact
Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out. But the overhead is much smaller than it sounds, and importantly, it's nowhere near your bottleneck....
|
[{"role":"AXLink","text":& [{"role":"AXLink","text":"Skip to content","depth":14,"bounds":{"left":0.029587766,"top":0.03830806,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Skip to content","depth":15,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Click to collapse","depth":16,"bounds":{"left":0.10239362,"top":0.06703911,"width":0.030585106,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10239362,"top":0.06703911,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":16,"bounds":{"left":0.10538564,"top":0.06703911,"width":0.027925532,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"⌘B","depth":16,"bounds":{"left":0.1349734,"top":0.06703911,"width":0.0063164895,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drag to resize","depth":16,"bounds":{"left":0.10239362,"top":0.079010375,"width":0.025930852,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.10239362,"top":0.079010375,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":13,"bounds":{"left":0.10538564,"top":0.079010375,"width":0.022938829,"height":0.011971269}}],"role_description":"text"},{"role":"AXButton","text":"Open sidebar","depth":14,"bounds":{"left":0.029920213,"top":0.02793296,"width":0.00930851,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat","depth":16,"bounds":{"left":0.004986702,"top":0.059856344,"width":0.025930852,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cowork","depth":16,"bounds":{"left":0.03158245,"top":0.059856344,"width":0.03125,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code","depth":16,"bounds":{"left":0.0631649,"top":0.059856344,"width":0.026928192,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New chat ⌘N","depth":15,"bounds":{"left":0.0043218085,"top":0.08938547,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New chat","depth":16,"bounds":{"left":0.014295213,"top":0.0933759,"width":0.018949468,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.014295213,"top":0.0933759,"width":0.003656915,"height":0.013567438}},{"char_start":1,"char_count":7,"bounds":{"left":0.01761968,"top":0.0933759,"width":0.015957447,"height":0.013567438}}],"role_description":"text"},{"role":"AXStaticText","text":"⌘N","depth":17,"bounds":{"left":0.08178192,"top":0.0933759,"width":0.006981383,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Projects","depth":15,"bounds":{"left":0.0043218085,"top":0.110135674,"width":0.08643617,"height":0.019952115},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Artifacts","depth":15,"bounds":{"left":0.0043218085,"top":0.1300878,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":15,"bounds":{"left":0.0043218085,"top":0.15003991,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pinned","depth":16,"bounds":{"left":0.0063164895,"top":0.18914606,"width":0.08377659,"height":0.013567438},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Bulgarian citizenship application process for EU residents","depth":18,"bounds":{"left":0.0043218085,"top":0.20590582,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Bulgarian citizenship application process for EU residents","depth":19,"bounds":{"left":0.08344415,"top":0.20909816,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Dawarich location tracking project","depth":18,"bounds":{"left":0.0043218085,"top":0.22745411,"width":0.08643617,"height":0.019952115},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Dawarich location tracking project","depth":19,"bounds":{"left":0.08344415,"top":0.22984837,"width":0.005984043,"height":0.015163607},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Recents","depth":16,"bounds":{"left":0.0063164895,"top":0.25698325,"width":0.06349734,"height":0.012769354},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"View all","depth":16,"bounds":{"left":0.07114362,"top":0.25698325,"width":0.018949468,"height":0.012769354},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit implementation strategy","depth":18,"bounds":{"left":0.0043218085,"top":0.27294493,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit implementation strategy","depth":19,"bounds":{"left":0.08344415,"top":0.27613726,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe retention policy code location","depth":18,"bounds":{"left":0.0043218085,"top":0.29449323,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe retention policy code location","depth":19,"bounds":{"left":0.08344415,"top":0.29768556,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Viewing retention policy in screenpipe","depth":18,"bounds":{"left":0.0043218085,"top":0.31524342,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Viewing retention policy in screenpipe","depth":19,"bounds":{"left":0.08344415,"top":0.31843576,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Clean shot x video recording termination issue","depth":18,"bounds":{"left":0.0043218085,"top":0.3367917,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Clean shot x video recording termination issue","depth":19,"bounds":{"left":0.08344415,"top":0.33998403,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit handling with executeRequest","depth":18,"bounds":{"left":0.0043218085,"top":0.3575419,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit handling with executeRequest","depth":19,"bounds":{"left":0.08344415,"top":0.36073422,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Untitled","depth":18,"bounds":{"left":0.0043218085,"top":0.3790902,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options","depth":19,"bounds":{"left":0.08344415,"top":0.38228253,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 Screen pipe. Is there ability…","depth":18,"bounds":{"left":0.0043218085,"top":0.39984038,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 Screen pipe. Is there ability…","depth":19,"bounds":{"left":0.08344415,"top":0.40303272,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"SMB mount access inconsistency between Finder and iTerm","depth":18,"bounds":{"left":0.0043218085,"top":0.42138866,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for SMB mount access inconsistency between Finder and iTerm","depth":19,"bounds":{"left":0.08344415,"top":0.4237829,"width":0.005984043,"height":0.015163607},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 What is the best switch I can…","depth":18,"bounds":{"left":0.0043218085,"top":0.44213888,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 What is the best switch I can…","depth":19,"bounds":{"left":0.08344415,"top":0.44533122,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Permission denied on screenpipe volume","depth":18,"bounds":{"left":0.0043218085,"top":0.46288908,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Permission denied on screenpipe volume","depth":19,"bounds":{"left":0.08344415,"top":0.4660814,"width":0.005984043,"height":0.015163607},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync database attachment error","depth":18,"bounds":{"left":0.0043218085,"top":0.48443735,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe sync database attachment error","depth":19,"bounds":{"left":0.08344415,"top":0.48762968,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Last swimming outing with Dani","depth":18,"bounds":{"left":0.0043218085,"top":0.5051876,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Last swimming outing with Dani","depth":19,"bounds":{"left":0.08344415,"top":0.5083799,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Definition of incarcerated","depth":18,"bounds":{"left":0.0043218085,"top":0.52673584,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Definition of incarcerated","depth":19,"bounds":{"left":0.08344415,"top":0.52992815,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chromecast remote volume buttons not working","depth":18,"bounds":{"left":0.0043218085,"top":0.547486,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Chromecast remote volume buttons not working","depth":19,"bounds":{"left":0.08344415,"top":0.5506784,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Salesforce API errors with Organization and FieldDefinition queries","depth":18,"bounds":{"left":0.0043218085,"top":0.56903434,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Salesforce API errors with Organization and FieldDefinition queries","depth":19,"bounds":{"left":0.08344415,"top":0.57222664,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Daily activity summary from screenpipe data","depth":18,"bounds":{"left":0.0043218085,"top":0.5897845,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Daily activity summary from screenpipe data","depth":19,"bounds":{"left":0.08344415,"top":0.59297687,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"MacBook unexpected restarts and kanji screen","depth":18,"bounds":{"left":0.0043218085,"top":0.6113328,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for MacBook unexpected restarts and kanji screen","depth":19,"bounds":{"left":0.08344415,"top":0.61452514,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Security patch review and testing guidance","depth":18,"bounds":{"left":0.0043218085,"top":0.632083,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Security patch review and testing guidance","depth":19,"bounds":{"left":0.08344415,"top":0.63527536,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Food calorie values reference","depth":18,"bounds":{"left":0.0043218085,"top":0.65363127,"width":0.08643617,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Food calorie values reference","depth":19,"bounds":{"left":0.08344415,"top":0.65682364,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tracking location history from last week","depth":18,"bounds":{"left":0.0043218085,"top":0.6743815,"width":0.08643617,"height":0.011173184},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Tracking location history from last week","depth":19,"bounds":{"left":0.08344415,"top":0.6775738,"width":0.005984043,"height":0.007980846},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Lukas Pro","depth":15,"bounds":{"left":0.0043218085,"top":0.6943336,"width":0.037898935,"height":0.01915403},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Get apps and extensions","depth":15,"bounds":{"left":0.08277926,"top":0.6943336,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit implementation strategy, rename chat","depth":19,"bounds":{"left":0.043218084,"top":0.02793296,"width":0.09773936,"height":0.022346368},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"HubSpot rate limit implementation strategy","depth":21,"bounds":{"left":0.04454787,"top":0.031923383,"width":0.09507979,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.04454787,"top":0.031923383,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":41,"bounds":{"left":0.048204787,"top":0.031923383,"width":0.09142287,"height":0.014365523}}],"role_description":"text"},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit implementation strategy","depth":19,"bounds":{"left":0.14128989,"top":0.02793296,"width":0.0066489363,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Share chat","depth":21,"bounds":{"left":0.48537233,"top":0.026336791,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Claude finished the response","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"You said: So just a solution for rate limit implementation.","depth":20,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: So just a solution for rate limit implementation.","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"So just a solution for rate limit implementation. The situation currently is that there are some daily and secondary limits for HubSpot. I would like to make sure I never reach a 429 error rate limit. The requests can come from any flow. It can be:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"updating activity (engagement, meeting, call, note)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"searching for a company or contact","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"updating deal","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"patching IDs\nReview what the limit is at the moment in the HubSpot documentation and then think of the solution:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"where to store it","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"how to read it","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"how to work with multiple jobs","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"how to work with paginated requests Let's consider a situation when there are 600 opportunities to sync. What would be the flow? How would the rate limit be recognized? How would it be handled? What are the potential issues? [API usage guidelines and limits - HubSpot docs](","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"). Example of such a error Client error:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST https://api.hubapi.com/crm/v3/objects/contact/search","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"resulted in a","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"429 Too Many Requests","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019dffc4-4 (truncated...). Think carefully about the implementation and potential issue and bottlenecks.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Show more","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10:42","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Claude responded: Current HubSpot limits (Apr 2026)","depth":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: Current HubSpot limits (Apr 2026)","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Synthesized HubSpot rate limit architecture with Redis storage and sliding window algorithms","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Synthesized HubSpot rate limit architecture with Redis storage and sliding window algorithms","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Current HubSpot limits (Apr 2026)","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Current HubSpot limits (Apr 2026)","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"For privately distributed apps (which is what Jiminny presumably uses with HubSpot), the limits are layered: a per-app burst window of 100/10s on Free/Starter, 190/10s on Pro/Enterprise, or 250/10s with the API Limit Increase add-on","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", plus a per-account daily cap of 250k / 625k / 1M depending on tier — shared across all private apps in the account","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". The burst window is per app; the daily quota is per portal.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":26,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":26,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The Search API is special: five requests per second per account, capped at 200 records per page, with a hard 10,000-result ceiling per query","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". That's the limit the 429 in your example is hitting (","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"secondly limit","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"on","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/crm/v3/objects/contact/search","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"). It's a separate bucket from the 190/10s, and critically, search responses do not include the","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"X-HubSpot-RateLimit-*","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"headers","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— you can't read remaining capacity off the response, you have to track it yourself.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":26,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":26,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Non-search endpoints return","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"X-HubSpot-RateLimit-Remaining","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-Max","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", and","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-Interval-Milliseconds","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". The daily headers are not returned for OAuth-authenticated calls","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", so for those you check the account-info endpoint or maintain your own counter. There's also a soft rule: errors should stay under 5% of total daily requests","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— that's enforced for marketplace listing, but it's also a sane operational target.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":26,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"hubspot","depth":26,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"So you have","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"four buckets","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"to track at minimum: app-burst (10s sliding), search-secondly (1s sliding), account-daily (24h fixed, midnight in HubSpot's TZ), and per-app daily share (your own budgeting on top of the account cap).","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Where to store it","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Where to store it","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redis. It's the only realistic option once you have multiple queue workers — DB-backed counters serialize too much, and in-process state can't coordinate across workers. Laravel already speaks Redis natively, and you get atomic","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INCR","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EXPIRE","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"plus Lua scripting for true CAS semantics.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Key layout I'd use:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy to clipboard","depth":27,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"hubspot:rl:burst:{portalId}:{appId} ZSET (sliding 10s)","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot:rl:search:{portalId} ZSET (sliding 1s)","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot:rl:daily:{portalId} STRING + TTL to midnight TZ","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot:rl:meta:{portalId} HASH (last seen headers)","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The two short-window buckets are sliding-window-log (Redis ZSET, score =","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"microtime","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", member = unique request id). Lua script removes entries older than the window, counts remaining slots, and only adds the new one if there's room — all atomic. Fixed windows are simpler but allow 2× the limit at the boundary, which on a 5/s window is brutal.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The daily bucket is a plain","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"INCR","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with TTL set to seconds-until-midnight in","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubSpot's account timezone","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", not yours — Sofia is UTC+2/+3 but your portal might be set to US Eastern. Get this once and cache it.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"How to read it","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"How to read it","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Two-phase: optimistic pre-check, authoritative post-update.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Before a call, run the Lua acquire script. If it returns \"denied,\" sleep until a slot frees up (the script can return ms-until-next-slot) or push the job back to the queue with a delay. Don't busy-loop.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"After the call, parse","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"X-HubSpot-RateLimit-Remaining","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-Max","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"-Interval-Milliseconds","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and store them in","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot:rl:meta:{portalId}","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":". This is your reality check — if your local counter says 50 remaining but HubSpot's header says 5, you trust HubSpot and clamp your counter. This handles clock drift, missed accounting (e.g., crashed worker that took a token but never made the request), and other apps in the same account consuming the daily budget invisibly.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"For search specifically, since headers don't come back, the local counter","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"is","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"the source of truth — meaning if you ever crash mid-flight, you've under-counted. Always release tokens on connection-level failure but","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"not","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"on 429 (you really did make that request).","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"How to work with multiple jobs","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"How to work with multiple jobs","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The queue layer needs to enforce concurrency separately from the rate limiter. Both work together:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Concurrency cap","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"via","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue::throttle()","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"or a Redis semaphore — limits how many sync workers run in parallel against HubSpot. Without this, you can have 50 workers all blocked waiting for tokens, which is wasteful and creates retry storms.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Per-tenant fairness","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— if you sync many Jiminny customers into different HubSpot portals, each portal has its own bucket but you still want one slow portal not to starve others. Either separate queues per portal or a fair-share scheduler.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Priority lanes","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— webhook-driven updates (user-visible latency) should outrank background batch syncs. Two queues:","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot-priority","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hubspot-bulk","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", with priority workers taking 70% of the burst budget and bulk taking 30% (enforce via separate sub-buckets if you really want hard separation, otherwise just pull from priority first).","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Backoff on 429","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— respect the","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Retry-After","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"header. If absent, exponential with jitter (e.g.,","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"min(2^attempt * 250ms, 30s) ± 20%","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"). The jitter is non-negotiable; without it, simultaneous 429s retry in lockstep and you get thundering-herd 429s on retry.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"How to work with paginated requests","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"How to work with paginated requests","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The trap is treating \"fetch all\" as one logical operation. Each page is its own API call and competes for tokens with everything else.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Two practical rules:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Don't hold the worker idle while paginating.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"If page N takes 500ms and page N+1 needs to wait 800ms for a token, you've burned 800ms of worker time doing nothing. Instead, fetch page N, dispatch the","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"processing","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"of page N as a separate job, and queue a \"fetch page N+1\" job with a delay equal to the wait time. Each page becomes its own atomic unit.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Always batch where HubSpot offers it.","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST /crm/v3/objects/{type}/batch/{read|update|create}","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"accepts up to 100 IDs per call. For your \"patching IDs\" flow this is the difference between 600 calls and 6.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Walkthrough: 600 opportunities","depth":24,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Walkthrough: 600 opportunities","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Naive flow (one PATCH per deal): 600 calls. At 190/10s that's ~32s of API time, well under daily. You'd hit burst easily without throttling. Plus likely 1-3 search calls upfront and N association calls.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sane flow:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Identify deltas","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— if you can avoid Search at all, do. Use","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"lastmodifieddate","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"filter on a single search if you must, paginate at limit=200. For 600 deals that's 3 search calls @ 5/s = ~600ms naturally throttled.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Batch read","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"current state —","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST /crm/v3/objects/deals/batch/read","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with 100 IDs per call → 6 calls. Burst weight 6.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Compute diff","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"in your code (no API).","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Batch update","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"—","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST /crm/v3/objects/deals/batch/update","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with 100 per call → 6 calls.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Associations","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"—","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"POST /crm/v4/associations/{from}/{to}/batch/create","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"if needed → another few batch calls.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Total: ~15-20 API calls for 600 deals. Burst budget consumed: 20/190 over ~5s. Daily impact: trivial.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Recognition: pre-check denies if","depth":25,"bounds":{"left":0.13164894,"top":0.019952115,"width":0.080119684,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.13164894,"top":0.015961692,"width":0.003656915,"height":0.016759777}},{"char_start":1,"char_count":31,"bounds":{"left":0.13530585,"top":0.015961692,"width":0.075465426,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"<weight>","depth":26,"bounds":{"left":0.2130984,"top":0.019952115,"width":0.022938829,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"slots aren't free; on 429 the response surfaces","depth":25,"bounds":{"left":0.23736702,"top":0.019952115,"width":0.112034574,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.23769946,"top":0.015961692,"width":0.0009973404,"height":0.016759777}},{"char_start":1,"char_count":46,"bounds":{"left":0.23869681,"top":0.015961692,"width":0.10837766,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"policyName","depth":26,"bounds":{"left":0.13297872,"top":0.03671189,"width":0.028922873,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.13331117,"top":0.03671189,"width":0.0026595744,"height":0.015163607}},{"char_start":1,"char_count":9,"bounds":{"left":0.13597074,"top":0.03671189,"width":0.025930852,"height":0.015163607}}],"role_description":"text"},{"role":"AXStaticText","text":"(DAILY/SECONDLY) — log it, push the job back with","depth":25,"bounds":{"left":0.16323139,"top":0.035115723,"width":0.13164894,"height":0.016759777},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.16323139,"top":0.035913806,"width":0.0013297872,"height":0.015961692}},{"char_start":1,"char_count":48,"bounds":{"left":0.16422872,"top":0.035913806,"width":0.1263298,"height":0.015961692}}],"role_description":"text"},{"role":"AXStaticText","text":"Retry-After","depth":26,"bounds":{"left":0.2962101,"top":0.03671189,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.2962101,"top":0.03671189,"width":0.0029920214,"height":0.015163607}},{"char_start":1,"char_count":10,"bounds":{"left":0.2992021,"top":0.03671189,"width":0.028922873,"height":0.015163607}}],"role_description":"text"},{"role":"AXStaticText","text":"delay, increment a metric so you can alarm on sustained 429 rate.","depth":25,"bounds":{"left":0.13164894,"top":0.035115723,"width":0.2130984,"height":0.035913806},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.32945478,"top":0.035913806,"width":0.0009973404,"height":0.015961692}},{"char_start":1,"char_count":64,"bounds":{"left":0.13164894,"top":0.035913806,"width":0.2130984,"height":0.035115723}}],"role_description":"text"},{"role":"AXHeading","text":"Pitfalls & bottlenecks worth pre-empting","depth":24,"bounds":{"left":0.12898937,"top":0.09098165,"width":0.24468085,"height":0.021548284},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"Pitfalls & bottlenecks worth pre-empting","depth":25,"bounds":{"left":0.13164894,"top":0.092577815,"width":0.11702128,"height":0.018355945},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.13164894,"top":0.092577815,"width":0.0039893617,"height":0.018355945}},{"char_start":1,"char_count":39,"bounds":{"left":0.1356383,"top":0.092577815,"width":0.11303192,"height":0.018355945}}],"role_description":"text"},{"role":"AXStaticText","text":"Daily quota is shared across the whole portal","depth":27,"bounds":{"left":0.14228724,"top":0.121308856,"width":0.11269947,"height":0.015961692},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14228724,"top":0.121308856,"width":0.0043218085,"height":0.016759777}},{"char_start":1,"char_count":44,"bounds":{"left":0.14660904,"top":0.121308856,"width":0.10837766,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":", including any n8n flows, other private apps, marketing automation calling APIs, etc. Budget for ~70-80% of the documented limit, not 100%. Add an internal per-app daily cap so a runaway sync can't starve other apps.","depth":26,"bounds":{"left":0.14228724,"top":0.121308856,"width":0.21043883,"height":0.07980846},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.2549867,"top":0.121308856,"width":0.0013297872,"height":0.016759777}},{"char_start":1,"char_count":216,"bounds":{"left":0.14228724,"top":0.121308856,"width":0.21010639,"height":0.07980846}}],"role_description":"text"},{"role":"AXStaticText","text":"Search is uniquely fragile","depth":27,"bounds":{"left":0.14228724,"top":0.20830008,"width":0.064494684,"height":0.016759777},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14228724,"top":0.20909816,"width":0.0033244682,"height":0.015961692}},{"char_start":1,"char_count":25,"bounds":{"left":0.1456117,"top":0.20909816,"width":0.061170213,"height":0.015961692}}],"role_description":"text"},{"role":"AXStaticText","text":": separate 5/s bucket, no headers to read, 10k-result cap per query. If you ever hit 10k+ deals matching a filter, partition by","depth":26,"bounds":{"left":0.14228724,"top":0.20830008,"width":0.20678191,"height":0.037509978},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.20678191,"top":0.20909816,"width":0.0013297872,"height":0.015961692}},{"char_start":1,"char_count":126,"bounds":{"left":0.14228724,"top":0.20909816,"width":0.20678191,"height":0.037509978}}],"role_description":"text"},{"role":"AXStaticText","text":"hs_object_id","depth":27,"bounds":{"left":0.2942154,"top":0.23064645,"width":0.034574468,"height":0.015163607},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.2942154,"top":0.23144454,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.29720744,"top":0.23144454,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"ranges or by","depth":26,"bounds":{"left":0.33011967,"top":0.22984837,"width":0.03158245,"height":0.015961692},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.33011967,"top":0.22984837,"width":0.0013297872,"height":0.016759777}},{"char_start":1,"char_count":11,"bounds":{"left":0.33111703,"top":0.22984837,"width":0.027260639,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"lastmodifieddate","depth":27,"bounds":{"left":0.14361702,"top":0.25219473,"width":0.046210106,"height":0.015163607},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14394946,"top":0.2529928,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.14660904,"top":0.2529928,"width":0.043218084,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"windows.","depth":26,"bounds":{"left":0.19115691,"top":0.25139666,"width":0.024601065,"height":0.015961692},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.19115691,"top":0.25139666,"width":0.0013297872,"height":0.016759777}},{"char_start":1,"char_count":7,"bounds":{"left":0.19215426,"top":0.25139666,"width":0.022606382,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"Retry storms after HubSpot incidents","depth":27,"bounds":{"left":0.14228724,"top":0.27613726,"width":0.09507979,"height":0.015961692},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14228724,"top":0.27613726,"width":0.0039893617,"height":0.016759777}},{"char_start":1,"char_count":35,"bounds":{"left":0.1462766,"top":0.27613726,"width":0.09142287,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"— always jitter, always cap total retries (e.g., 5 attempts, then dead-letter).","depth":26,"bounds":{"left":0.14228724,"top":0.27613726,"width":0.20678191,"height":0.037509978},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.23736702,"top":0.27613726,"width":0.0013297872,"height":0.016759777}},{"char_start":1,"char_count":78,"bounds":{"left":0.14228724,"top":0.27613726,"width":0.20678191,"height":0.037509978}}],"role_description":"text"},{"role":"AXStaticText","text":"Webhook → sync → webhook loops","depth":27,"bounds":{"left":0.14228724,"top":0.32083002,"width":0.087101065,"height":0.016759777},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14228724,"top":0.3216281,"width":0.005319149,"height":0.015961692}},{"char_start":1,"char_count":29,"bounds":{"left":0.14760639,"top":0.3216281,"width":0.08178192,"height":0.015961692}}],"role_description":"text"},{"role":"AXStaticText","text":"— when your update fires a HubSpot webhook that triggers another sync. Tag your own writes (e.g., a custom property","depth":26,"bounds":{"left":0.14228724,"top":0.32083002,"width":0.21343085,"height":0.037509978},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.2293883,"top":0.3216281,"width":0.0013297872,"height":0.015961692}},{"char_start":1,"char_count":114,"bounds":{"left":0.14228724,"top":0.3216281,"width":0.21343085,"height":0.037509978}}],"role_description":"text"},{"role":"AXStaticText","text":"jy_last_sync_id","depth":27,"bounds":{"left":0.3075133,"top":0.34317636,"width":0.043218084,"height":0.015163607},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.3075133,"top":0.34397447,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.31050533,"top":0.34397447,"width":0.040226065,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":") and ignore webhooks where it just changed.","depth":26,"bounds":{"left":0.14228724,"top":0.3423783,"width":0.21210106,"height":0.037509978},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.35206118,"top":0.3423783,"width":0.0023271276,"height":0.016759777}},{"char_start":1,"char_count":43,"bounds":{"left":0.14228724,"top":0.3639266,"width":0.107380316,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"Token refresh","depth":27,"bounds":{"left":0.14228724,"top":0.38786912,"width":0.03557181,"height":0.016759777},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14228724,"top":0.3886672,"width":0.0033244682,"height":0.015961692}},{"char_start":1,"char_count":12,"bounds":{"left":0.1456117,"top":0.3886672,"width":0.032247342,"height":0.015961692}}],"role_description":"text"},{"role":"AXStaticText","text":"— OAuth refresh itself counts against burst. Cache the access token in Redis with TTL =","depth":26,"bounds":{"left":0.14228724,"top":0.38786912,"width":0.20744681,"height":0.037509978},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.17785904,"top":0.3886672,"width":0.0009973404,"height":0.015961692}},{"char_start":1,"char_count":86,"bounds":{"left":0.14228724,"top":0.3886672,"width":0.20744681,"height":0.037509978}}],"role_description":"text"},{"role":"AXStaticText","text":"expires_in - 60s","depth":27,"bounds":{"left":0.18650267,"top":0.4102155,"width":0.046210106,"height":0.015163607},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.18683511,"top":0.41101357,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.18949468,"top":0.41101357,"width":0.043218084,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":", single-flight the refresh (only one worker refreshes; others wait on a lock).","depth":26,"bounds":{"left":0.14228724,"top":0.4094174,"width":0.22041224,"height":0.037509978},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.23404256,"top":0.4094174,"width":0.0013297872,"height":0.016759777}},{"char_start":1,"char_count":78,"bounds":{"left":0.14228724,"top":0.4094174,"width":0.2200798,"height":0.037509978}}],"role_description":"text"},{"role":"AXStaticText","text":"Search latency for fresh writes","depth":27,"bounds":{"left":0.14228724,"top":0.45490822,"width":0.07712766,"height":0.015961692},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14228724,"top":0.45490822,"width":0.0033244682,"height":0.016759777}},{"char_start":1,"char_count":30,"bounds":{"left":0.1456117,"top":0.45490822,"width":0.073803194,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"— newly created/updated objects don't appear in search instantly. Don't write-then-search; use returned IDs directly.","depth":26,"bounds":{"left":0.14228724,"top":0.45490822,"width":0.21509309,"height":0.037509978},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.21941489,"top":0.45490822,"width":0.0009973404,"height":0.016759777}},{"char_start":1,"char_count":116,"bounds":{"left":0.14228724,"top":0.45490822,"width":0.21509309,"height":0.037509978}}],"role_description":"text"},{"role":"AXStaticText","text":"Clock skew","depth":27,"bounds":{"left":0.14228724,"top":0.50039905,"width":0.028922873,"height":0.015961692},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14228724,"top":0.50039905,"width":0.0039893617,"height":0.016759777}},{"char_start":1,"char_count":9,"bounds":{"left":0.1462766,"top":0.50039905,"width":0.025265958,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"— Redis is authoritative. Don't use","depth":26,"bounds":{"left":0.17121011,"top":0.50039905,"width":0.08577128,"height":0.015961692},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.17121011,"top":0.50039905,"width":0.0013297872,"height":0.016759777}},{"char_start":1,"char_count":34,"bounds":{"left":0.17220744,"top":0.50039905,"width":0.08111702,"height":0.016759777}}],"role_description":"text"},{"role":"AXStaticText","text":"time()","depth":27,"bounds":{"left":0.25831118,"top":0.5011971,"width":0.01761968,"height":0.015163607},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.25864363,"top":0.5019952,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.2613032,"top":0.5019952,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"from each worker for window scoring; use","depth":26,"bounds":{"left":0.14228724,"top":0.50039905,"width":0.20844415,"height":0.037509978},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.27726063,"top":0.50039905,"width":0.0009973404,"height":0.016759777}},{"char_start":1,"char_count":39,"bounds":{"left":0.14228724,"top":0.50039905,"width":0.20844415,"height":0.03830806}}],"role_description":"text"},{"role":"AXStaticText","text":"redis.call('TIME')","depth":27,"bounds":{"left":0.17386968,"top":0.52274543,"width":0.051861703,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"inside the Lua script.","depth":26,"bounds":{"left":0.22706117,"top":0.5219473,"width":0.05219415,"height":0.015961692},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Dead workers with held tokens","depth":27,"bounds":{"left":0.14228724,"top":0.54588985,"width":0.078457445,"height":0.016759777},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"— sliding-window-log handles this naturally because tokens expire by score; token-bucket implementations need explicit release-on-crash logic.","depth":26,"bounds":{"left":0.14228724,"top":0.54588985,"width":0.21010639,"height":0.05905826},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"The 5% error rule","depth":27,"bounds":{"left":0.14228724,"top":0.612929,"width":0.044215426,"height":0.015961692},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"counts every 429 toward your error budget, even successfully retried ones. If your pre-check is working well, 429s should be near zero — if they're not, your pre-check is wrong, not just slow.","depth":26,"bounds":{"left":0.14228724,"top":0.612929,"width":0.22041224,"height":0.058260176},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Phantom contention with Laravel","depth":27,"bounds":{"left":0.14228724,"top":0.67917,"width":0.08610372,"height":0.015961692},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"RateLimited","depth":28,"bounds":{"left":0.22972074,"top":0.67996806,"width":0.031914894,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"middleware","depth":27,"bounds":{"left":0.2629654,"top":0.67917,"width":0.03158245,"height":0.015961692},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":": it's per-job-class by default, not per-portal. If your","depth":26,"bounds":{"left":0.14228724,"top":0.67917,"width":0.20212767,"height":0.037509978},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncDealJob","depth":27,"bounds":{"left":0.21708776,"top":0.7015164,"width":0.031914894,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"and","depth":26,"bounds":{"left":0.25033244,"top":0.7007183,"width":0.011635638,"height":0.015961692},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateActivityJob","depth":27,"bounds":{"left":0.2632979,"top":0.7015164,"width":0.04920213,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"are different classes both calling HubSpot, they don't share a Laravel-level limiter — you need a single","depth":26,"bounds":{"left":0.14228724,"top":0.7007183,"width":0.2174202,"height":0.037509978},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HubspotRateLimiter","depth":27,"bounds":{"left":0.14361702,"top":0.7438148,"width":0.051861703,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"service that everything routes through.","depth":26,"bounds":{"left":0.19680852,"top":0.7430168,"width":0.09740692,"height":0.015961692},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"If you want, I can sketch the Lua script for the sliding-window acquire and the Laravel service wrapper around it.","depth":25,"bounds":{"left":0.13164894,"top":0.782921,"width":0.22772606,"height":0.035115723},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Copy","depth":22,"bounds":{"left":0.12898937,"top":0.8292099,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give positive feedback","depth":22,"bounds":{"left":0.13962767,"top":0.8292099,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give negative feedback","depth":22,"bounds":{"left":0.15026596,"top":0.8292099,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Retry","depth":22,"bounds":{"left":0.16090426,"top":0.8292099,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"You said: What will happen if there are two different types of rate limits?","depth":20,"bounds":{"left":0.12865691,"top":0.8731046,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"You said: What will happen if there are two different types of rate limits?","depth":21,"bounds":{"left":0.12865691,"top":0.8731046,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"What will happen if there are two different types of rate limits?","depth":24,"bounds":{"left":0.17087767,"top":0.88427776,"width":0.15724733,"height":0.015961692},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Search requests that have 5 requests per second","depth":25,"bounds":{"left":0.18151596,"top":0.9082203,"width":0.122340426,"height":0.016759777},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"The other rate limit that has, let's say, 100 requests per 10 seconds How do these work together? Is there some conflict? Can I reach the limit with one request and block either as well, or are these separated? Can I still continue making search requests once I hit the normal requests limits?","depth":25,"bounds":{"left":0.18151596,"top":0.9265762,"width":0.18550532,"height":0.06943336},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"13:40","depth":22,"bounds":{"left":0.32945478,"top":0.9992019,"width":0.009640957,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":22,"bounds":{"left":0.34175533,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":22,"bounds":{"left":0.35239363,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":22,"bounds":{"left":0.36303192,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Claude responded: They're independent buckets — with one shared bucket on top.","depth":21,"bounds":{"left":0.12865691,"top":0.9992019,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: They're independent buckets — with one shared bucket on top.","depth":22,"bounds":{"left":0.12865691,"top":0.9992019,"width":0.20611702,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Analyzed independent rate limit buckets and their practical interactions","depth":22,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.24202128,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzed independent rate limit buckets and their practical interactions","depth":23,"bounds":{"left":0.13131648,"top":0.9992019,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"They're independent buckets — with one shared bucket on top.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.1549202,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"The three buckets and what each call hits","depth":24,"bounds":{"left":0.12898937,"top":0.9992019,"width":0.24468085,"height":0.0007980846},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"The three buckets and what each call hits","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.11735372,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Copy to clipboard","depth":27,"bounds":{"left":0.36037233,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"┌──────────────────┐","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.12034574,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Search request ──→ │ Search: 5/sec │ ──┐","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.13131648,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"└──────────────────┘ │","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.13131648,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"├──→ ┌─────────────────┐","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.19581117,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"┌──────────────────┐ │ │ Daily: 250k–1M │","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.19581117,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Non-search call ──→ │ Burst: 190/10s │ ──┘ │ (per portal) │","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.19581117,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"└──────────────────┘ └─────────────────┘","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.19581117,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"A search call is only metered against the search bucket and the daily bucket. A non-search call (batch read/update, single PATCH, associations, etc.) is only metered against the burst bucket and the daily bucket. The two short-window buckets do not share counters.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.23005319,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"What this means practically","depth":24,"bounds":{"left":0.12898937,"top":0.9992019,"width":0.24468085,"height":0.0007980846},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"What this means practically","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.080119684,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hitting search secondly limit (5/s):","depth":26,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.08743351,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Only further","depth":25,"bounds":{"left":0.21875,"top":0.9992019,"width":0.03324468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"/search","depth":26,"bounds":{"left":0.25332448,"top":0.9992019,"width":0.020279255,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"calls 429. Your batch reads, batch updates, single PATCHes, association calls — all keep working at full burst speed. This is actually useful: if your sync is bottlenecked on Search, you can pivot to using","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22539894,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"lastmodifieddate","depth":26,"bounds":{"left":0.13297872,"top":0.9992019,"width":0.046210106,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"filters via batch endpoints, or use the IDs you already have to do batch reads, while Search cools off.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22041224,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hitting burst limit (190/10s):","depth":26,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.07280585,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Only non-search calls 429. You can still issue Search calls at 5/s. Useful for: continuing to identify deltas for queueing while in-flight updates drain, or refreshing a small set of records via Search even though your write pipeline is paused.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22805852,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hitting daily limit:","depth":26,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.046875,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Everything stops. Search and non-search alike. Doesn't unblock until midnight in your portal's configured timezone — and remember this is shared across every private app in the portal, plus n8n flows, marketing tools, anything else hitting the API with that account.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22240691,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"So can one type of request block the other?","depth":24,"bounds":{"left":0.12898937,"top":0.9992019,"width":0.24468085,"height":0.0007980846},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"So can one type of request block the other?","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.12134308,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Search → Burst:","depth":26,"bounds":{"left":0.14228724,"top":0.9992019,"width":0.039228722,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"No.","depth":27,"bounds":{"left":0.18118352,"top":0.9992019,"width":0.008976064,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Saturating Search at 50 calls per 10s leaves your full 190/10s burst untouched.","depth":26,"bounds":{"left":0.14228724,"top":0.9992019,"width":0.20844415,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Burst → Search:","depth":26,"bounds":{"left":0.14228724,"top":0.9992019,"width":0.039228722,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"No.","depth":27,"bounds":{"left":0.18118352,"top":0.9992019,"width":0.008976064,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Saturating burst leaves Search's 5/s untouched.","depth":26,"bounds":{"left":0.18982713,"top":0.9992019,"width":0.11668883,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Either → Daily:","depth":26,"bounds":{"left":0.14228724,"top":0.9992019,"width":0.03723404,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yes","depth":27,"bounds":{"left":0.17918883,"top":0.9992019,"width":0.00930851,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":", but only by contributing to the same daily counter. It's volume that kills you here, not the type.","depth":26,"bounds":{"left":0.14228724,"top":0.9992019,"width":0.21110372,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"In theory you can sustain ~50 search + ~190 other =","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.12732713,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"~240 calls per 10 seconds","depth":26,"bounds":{"left":0.25864363,"top":0.9992019,"width":0.064494684,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"indefinitely (until daily runs out), because the two buckets bill independently.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22140957,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"Implementation consequence","depth":24,"bounds":{"left":0.12898937,"top":0.9992019,"width":0.24468085,"height":0.0007980846},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"Implementation consequence","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.08543883,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Your rate limiter needs to know which bucket a request hits before it acquires. Cleanest pattern:","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.21210106,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Copy to clipboard","depth":27,"bounds":{"left":0.36037233,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"php","depth":26,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.0076462766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"$limiter","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.022606382,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"->","depth":27,"bounds":{"left":0.15591756,"top":0.9992019,"width":0.005984043,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"acquire","depth":27,"bounds":{"left":0.16156915,"top":0.9992019,"width":0.019614361,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.18118352,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"'search'","depth":27,"bounds":{"left":0.18384309,"top":0.9992019,"width":0.022606382,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":",","depth":27,"bounds":{"left":0.20611702,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.20910904,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"$weight","depth":27,"bounds":{"left":0.21176861,"top":0.9992019,"width":0.019946808,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":27,"bounds":{"left":0.23138298,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":27,"bounds":{"left":0.23404256,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.23703457,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":";","depth":27,"bounds":{"left":0.23969415,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.24268617,"top":0.9992019,"width":0.00831117,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"// for search endpoints only","depth":27,"bounds":{"left":0.25099733,"top":0.9992019,"width":0.078457445,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$limiter","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.022606382,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"->","depth":27,"bounds":{"left":0.15591756,"top":0.9992019,"width":0.005984043,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"acquire","depth":27,"bounds":{"left":0.16156915,"top":0.9992019,"width":0.019614361,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.18118352,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"'burst'","depth":27,"bounds":{"left":0.18384309,"top":0.9992019,"width":0.019946808,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":",","depth":27,"bounds":{"left":0.20345744,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.20611702,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"$weight","depth":27,"bounds":{"left":0.20910904,"top":0.9992019,"width":0.019614361,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":27,"bounds":{"left":0.2287234,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":27,"bounds":{"left":0.23138298,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.23404256,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":";","depth":27,"bounds":{"left":0.23703457,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.23969415,"top":0.9992019,"width":0.011303191,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"// for everything else","depth":27,"bounds":{"left":0.25099733,"top":0.9992019,"width":0.061835106,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"$limiter","depth":27,"bounds":{"left":0.13364361,"top":0.9992019,"width":0.022606382,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"->","depth":27,"bounds":{"left":0.15591756,"top":0.9992019,"width":0.005984043,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"acquire","depth":27,"bounds":{"left":0.16156915,"top":0.9992019,"width":0.019614361,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.18118352,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"'daily'","depth":27,"bounds":{"left":0.18384309,"top":0.9992019,"width":0.019946808,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":",","depth":27,"bounds":{"left":0.20345744,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.20611702,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"$weight","depth":27,"bounds":{"left":0.20910904,"top":0.9992019,"width":0.019614361,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"=","depth":27,"bounds":{"left":0.2287234,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":27,"bounds":{"left":0.23138298,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.23404256,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":";","depth":27,"bounds":{"left":0.23703457,"top":0.9992019,"width":0.0029920214,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.23969415,"top":0.9992019,"width":0.011303191,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"// every call, both kinds","depth":27,"bounds":{"left":0.25099733,"top":0.9992019,"width":0.07014628,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"In Redis: three separate keys, three separate Lua acquire scripts (or one script with a bucket parameter). A search call calls","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22240691,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"acquire('search')","depth":26,"bounds":{"left":0.20744681,"top":0.9992019,"width":0.04886968,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":25,"bounds":{"left":0.25764626,"top":0.9992019,"width":0.0056515955,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"acquire('daily')","depth":26,"bounds":{"left":0.26462767,"top":0.9992019,"width":0.04654255,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":". A batch update calls","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22074468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"acquire('burst')","depth":26,"bounds":{"left":0.14527926,"top":0.9992019,"width":0.045877658,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":25,"bounds":{"left":0.1924867,"top":0.9992019,"width":0.0056515955,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"acquire('daily')","depth":26,"bounds":{"left":0.19946809,"top":0.9992019,"width":0.046210106,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".","depth":25,"bounds":{"left":0.24700798,"top":0.9992019,"width":0.0013297872,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"One subtle pitfall: when you backoff on a 429,","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.112034574,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"inspect","depth":26,"bounds":{"left":0.24368352,"top":0.9992019,"width":0.019946808,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"policyName","depth":27,"bounds":{"left":0.2649601,"top":0.9992019,"width":0.02925532,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"in the response body","depth":26,"bounds":{"left":0.29554522,"top":0.9992019,"width":0.053856384,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"to know which bucket actually fired. If you see","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.2237367,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SECONDLY","depth":26,"bounds":{"left":0.24102394,"top":0.9992019,"width":0.023271276,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"from a search endpoint, you only need to delay search-bound jobs — burst-bound jobs in the queue can keep running. If you blanket-pause everything on any 429, you waste capacity on the bucket that's still healthy. Two queues (or two throttle keys) make this clean; one global pause is the lazy version.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.23038563,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"The other subtlety: the burst response gives you","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.11868351,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"X-HubSpot-RateLimit-Remaining","depth":26,"bounds":{"left":0.25166222,"top":0.9992019,"width":0.08344415,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"to clamp local state against, but search doesn't return those headers. So your search counter is unverified — be slightly more conservative there (e.g., budget 4/s instead of 5) to absorb the unaccounted-for calls.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22739361,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Copy","depth":22,"bounds":{"left":0.12898937,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give positive feedback","depth":22,"bounds":{"left":0.13962767,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Give negative feedback","depth":22,"bounds":{"left":0.15026596,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Retry","depth":22,"bounds":{"left":0.16090426,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"You said: Ok, so what will happen each time I make a request?","depth":20,"bounds":{"left":0.12865691,"top":0.9992019,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"You said: Ok, so what will happen each time I make a request?","depth":21,"bounds":{"left":0.12865691,"top":0.9992019,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ok, so what will happen each time I make a request? Let's say I have 100,000 requests to make that are instant. Do I need to increment each request based on the type? For example, if there is a search request, I need to increment both the search bucket and also the daily bucket. If it's a burst, then I can go to the daily and burst buckets. If I need to check if it can make a call, do I need to see both the daily and search, or burst, respectively? Isn't that too heavy for the infrastructure, adding additional load to each request?","depth":24,"bounds":{"left":0.17087767,"top":0.9992019,"width":0.19680852,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"13:44","depth":22,"bounds":{"left":0.32945478,"top":0.9992019,"width":0.009640957,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":22,"bounds":{"left":0.34175533,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":22,"bounds":{"left":0.35239363,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":22,"bounds":{"left":0.36303192,"top":0.9992019,"width":0.010638298,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Claude responded: Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out.","depth":21,"bounds":{"left":0.12865691,"top":0.9992019,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out.","depth":22,"bounds":{"left":0.12865691,"top":0.9992019,"width":0.37134308,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Analyzed per-request overhead concerns and quantified Redis performance impact","depth":22,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.24202128,"height":0.0007980846},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzed per-request overhead concerns and quantified Redis performance impact","depth":23,"bounds":{"left":0.13131648,"top":0.9992019,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out. But the overhead is much smaller than it sounds, and importantly, it's nowhere near your bottleneck.","depth":25,"bounds":{"left":0.13164894,"top":0.9992019,"width":0.22706117,"height":0.0007980846},"on_screen":true,"role_description":"text"}]...
|
-9079156757604977979
|
3462968482044140636
|
click
|
accessibility
|
NULL
|
Skip to content
Skip to content
Click to collapse
Skip to content
Skip to content
Click to collapse
⌘B
Drag to resize
Open sidebar
Chat
Cowork
Code
New chat ⌘N
New chat
⌘N
Projects
Artifacts
Customize
Pinned
Bulgarian citizenship application process for EU residents
More options for Bulgarian citizenship application process for EU residents
Dawarich location tracking project
More options for Dawarich location tracking project
Recents
View all
HubSpot rate limit implementation strategy
More options for HubSpot rate limit implementation strategy
Screenpipe retention policy code location
More options for Screenpipe retention policy code location
Viewing retention policy in screenpipe
More options for Viewing retention policy in screenpipe
Clean shot x video recording termination issue
More options for Clean shot x video recording termination issue
HubSpot rate limit handling with executeRequest
More options for HubSpot rate limit handling with executeRequest
Untitled
More options
💬 Screen pipe. Is there ability…
More options for 💬 Screen pipe. Is there ability…
SMB mount access inconsistency between Finder and iTerm
More options for SMB mount access inconsistency between Finder and iTerm
💬 What is the best switch I can…
More options for 💬 What is the best switch I can…
Permission denied on screenpipe volume
More options for Permission denied on screenpipe volume
Screenpipe sync database attachment error
More options for Screenpipe sync database attachment error
Last swimming outing with Dani
More options for Last swimming outing with Dani
Definition of incarcerated
More options for Definition of incarcerated
Chromecast remote volume buttons not working
More options for Chromecast remote volume buttons not working
Salesforce API errors with Organization and FieldDefinition queries
More options for Salesforce API errors with Organization and FieldDefinition queries
Daily activity summary from screenpipe data
More options for Daily activity summary from screenpipe data
MacBook unexpected restarts and kanji screen
More options for MacBook unexpected restarts and kanji screen
Security patch review and testing guidance
More options for Security patch review and testing guidance
Food calorie values reference
More options for Food calorie values reference
Tracking location history from last week
More options for Tracking location history from last week
Lukas Pro
Get apps and extensions
HubSpot rate limit implementation strategy, rename chat
HubSpot rate limit implementation strategy
More options for HubSpot rate limit implementation strategy
Share chat
Claude finished the response
You said: So just a solution for rate limit implementation.
You said: So just a solution for rate limit implementation.
So just a solution for rate limit implementation. The situation currently is that there are some daily and secondary limits for HubSpot. I would like to make sure I never reach a 429 error rate limit. The requests can come from any flow. It can be:
updating activity (engagement, meeting, call, note)
searching for a company or contact
updating deal
patching IDs
Review what the limit is at the moment in the HubSpot documentation and then think of the solution:
where to store it
how to read it
how to work with multiple jobs
how to work with paginated requests Let's consider a situation when there are 600 opportunities to sync. What would be the flow? How would the rate limit be recognized? How would it be handled? What are the potential issues? [API usage guidelines and limits - HubSpot docs](
https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines
https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines
). Example of such a error Client error:
POST https://api.hubapi.com/crm/v3/objects/contact/search
resulted in a
429 Too Many Requests
response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT","correlationId":"019dffc4-4 (truncated...). Think carefully about the implementation and potential issue and bottlenecks.
Show more
10:42
Retry
Edit
Copy
Claude responded: Current HubSpot limits (Apr 2026)
Claude responded: Current HubSpot limits (Apr 2026)
Synthesized HubSpot rate limit architecture with Redis storage and sliding window algorithms
Synthesized HubSpot rate limit architecture with Redis storage and sliding window algorithms
Current HubSpot limits (Apr 2026)
Current HubSpot limits (Apr 2026)
For privately distributed apps (which is what Jiminny presumably uses with HubSpot), the limits are layered: a per-app burst window of 100/10s on Free/Starter, 190/10s on Pro/Enterprise, or 250/10s with the API Limit Increase add-on
, plus a per-account daily cap of 250k / 625k / 1M depending on tier — shared across all private apps in the account
. The burst window is per app; the daily quota is per portal.
hubspot
hubspot
hubspot
hubspot
The Search API is special: five requests per second per account, capped at 200 records per page, with a hard 10,000-result ceiling per query
. That's the limit the 429 in your example is hitting (
secondly limit
on
/crm/v3/objects/contact/search
). It's a separate bucket from the 190/10s, and critically, search responses do not include the
X-HubSpot-RateLimit-*
headers
— you can't read remaining capacity off the response, you have to track it yourself.
hubspot
hubspot
hubspot
hubspot
Non-search endpoints return
X-HubSpot-RateLimit-Remaining
,
-Max
, and
-Interval-Milliseconds
. The daily headers are not returned for OAuth-authenticated calls
, so for those you check the account-info endpoint or maintain your own counter. There's also a soft rule: errors should stay under 5% of total daily requests
— that's enforced for marketplace listing, but it's also a sane operational target.
hubspot
hubspot
hubspot
hubspot
So you have
four buckets
to track at minimum: app-burst (10s sliding), search-secondly (1s sliding), account-daily (24h fixed, midnight in HubSpot's TZ), and per-app daily share (your own budgeting on top of the account cap).
Where to store it
Where to store it
Redis. It's the only realistic option once you have multiple queue workers — DB-backed counters serialize too much, and in-process state can't coordinate across workers. Laravel already speaks Redis natively, and you get atomic
INCR
/
EXPIRE
plus Lua scripting for true CAS semantics.
Key layout I'd use:
Copy to clipboard
hubspot:rl:burst:{portalId}:{appId} ZSET (sliding 10s)
hubspot:rl:search:{portalId} ZSET (sliding 1s)
hubspot:rl:daily:{portalId} STRING + TTL to midnight TZ
hubspot:rl:meta:{portalId} HASH (last seen headers)
The two short-window buckets are sliding-window-log (Redis ZSET, score =
microtime
, member = unique request id). Lua script removes entries older than the window, counts remaining slots, and only adds the new one if there's room — all atomic. Fixed windows are simpler but allow 2× the limit at the boundary, which on a 5/s window is brutal.
The daily bucket is a plain
INCR
with TTL set to seconds-until-midnight in
HubSpot's account timezone
, not yours — Sofia is UTC+2/+3 but your portal might be set to US Eastern. Get this once and cache it.
How to read it
How to read it
Two-phase: optimistic pre-check, authoritative post-update.
Before a call, run the Lua acquire script. If it returns "denied," sleep until a slot frees up (the script can return ms-until-next-slot) or push the job back to the queue with a delay. Don't busy-loop.
After the call, parse
X-HubSpot-RateLimit-Remaining
/
-Max
/
-Interval-Milliseconds
and store them in
hubspot:rl:meta:{portalId}
. This is your reality check — if your local counter says 50 remaining but HubSpot's header says 5, you trust HubSpot and clamp your counter. This handles clock drift, missed accounting (e.g., crashed worker that took a token but never made the request), and other apps in the same account consuming the daily budget invisibly.
For search specifically, since headers don't come back, the local counter
is
the source of truth — meaning if you ever crash mid-flight, you've under-counted. Always release tokens on connection-level failure but
not
on 429 (you really did make that request).
How to work with multiple jobs
How to work with multiple jobs
The queue layer needs to enforce concurrency separately from the rate limiter. Both work together:
Concurrency cap
via
Queue::throttle()
or a Redis semaphore — limits how many sync workers run in parallel against HubSpot. Without this, you can have 50 workers all blocked waiting for tokens, which is wasteful and creates retry storms.
Per-tenant fairness
— if you sync many Jiminny customers into different HubSpot portals, each portal has its own bucket but you still want one slow portal not to starve others. Either separate queues per portal or a fair-share scheduler.
Priority lanes
— webhook-driven updates (user-visible latency) should outrank background batch syncs. Two queues:
hubspot-priority
and
hubspot-bulk
, with priority workers taking 70% of the burst budget and bulk taking 30% (enforce via separate sub-buckets if you really want hard separation, otherwise just pull from priority first).
Backoff on 429
— respect the
Retry-After
header. If absent, exponential with jitter (e.g.,
min(2^attempt * 250ms, 30s) ± 20%
). The jitter is non-negotiable; without it, simultaneous 429s retry in lockstep and you get thundering-herd 429s on retry.
How to work with paginated requests
How to work with paginated requests
The trap is treating "fetch all" as one logical operation. Each page is its own API call and competes for tokens with everything else.
Two practical rules:
Don't hold the worker idle while paginating.
If page N takes 500ms and page N+1 needs to wait 800ms for a token, you've burned 800ms of worker time doing nothing. Instead, fetch page N, dispatch the
processing
of page N as a separate job, and queue a "fetch page N+1" job with a delay equal to the wait time. Each page becomes its own atomic unit.
Always batch where HubSpot offers it.
POST /crm/v3/objects/{type}/batch/{read|update|create}
accepts up to 100 IDs per call. For your "patching IDs" flow this is the difference between 600 calls and 6.
Walkthrough: 600 opportunities
Walkthrough: 600 opportunities
Naive flow (one PATCH per deal): 600 calls. At 190/10s that's ~32s of API time, well under daily. You'd hit burst easily without throttling. Plus likely 1-3 search calls upfront and N association calls.
Sane flow:
Identify deltas
— if you can avoid Search at all, do. Use
lastmodifieddate
filter on a single search if you must, paginate at limit=200. For 600 deals that's 3 search calls @ 5/s = ~600ms naturally throttled.
Batch read
current state —
POST /crm/v3/objects/deals/batch/read
with 100 IDs per call → 6 calls. Burst weight 6.
Compute diff
in your code (no API).
Batch update
—
POST /crm/v3/objects/deals/batch/update
with 100 per call → 6 calls.
Associations
—
POST /crm/v4/associations/{from}/{to}/batch/create
if needed → another few batch calls.
Total: ~15-20 API calls for 600 deals. Burst budget consumed: 20/190 over ~5s. Daily impact: trivial.
Recognition: pre-check denies if
<weight>
slots aren't free; on 429 the response surfaces
policyName
(DAILY/SECONDLY) — log it, push the job back with
Retry-After
delay, increment a metric so you can alarm on sustained 429 rate.
Pitfalls & bottlenecks worth pre-empting
Pitfalls & bottlenecks worth pre-empting
Daily quota is shared across the whole portal
, including any n8n flows, other private apps, marketing automation calling APIs, etc. Budget for ~70-80% of the documented limit, not 100%. Add an internal per-app daily cap so a runaway sync can't starve other apps.
Search is uniquely fragile
: separate 5/s bucket, no headers to read, 10k-result cap per query. If you ever hit 10k+ deals matching a filter, partition by
hs_object_id
ranges or by
lastmodifieddate
windows.
Retry storms after HubSpot incidents
— always jitter, always cap total retries (e.g., 5 attempts, then dead-letter).
Webhook → sync → webhook loops
— when your update fires a HubSpot webhook that triggers another sync. Tag your own writes (e.g., a custom property
jy_last_sync_id
) and ignore webhooks where it just changed.
Token refresh
— OAuth refresh itself counts against burst. Cache the access token in Redis with TTL =
expires_in - 60s
, single-flight the refresh (only one worker refreshes; others wait on a lock).
Search latency for fresh writes
— newly created/updated objects don't appear in search instantly. Don't write-then-search; use returned IDs directly.
Clock skew
— Redis is authoritative. Don't use
time()
from each worker for window scoring; use
redis.call('TIME')
inside the Lua script.
Dead workers with held tokens
— sliding-window-log handles this naturally because tokens expire by score; token-bucket implementations need explicit release-on-crash logic.
The 5% error rule
counts every 429 toward your error budget, even successfully retried ones. If your pre-check is working well, 429s should be near zero — if they're not, your pre-check is wrong, not just slow.
Phantom contention with Laravel
RateLimited
middleware
: it's per-job-class by default, not per-portal. If your
SyncDealJob
and
UpdateActivityJob
are different classes both calling HubSpot, they don't share a Laravel-level limiter — you need a single
HubspotRateLimiter
service that everything routes through.
If you want, I can sketch the Lua script for the sliding-window acquire and the Laravel service wrapper around it.
Copy
Give positive feedback
Give negative feedback
Retry
You said: What will happen if there are two different types of rate limits?
You said: What will happen if there are two different types of rate limits?
What will happen if there are two different types of rate limits?
Search requests that have 5 requests per second
The other rate limit that has, let's say, 100 requests per 10 seconds How do these work together? Is there some conflict? Can I reach the limit with one request and block either as well, or are these separated? Can I still continue making search requests once I hit the normal requests limits?
13:40
Retry
Edit
Copy
Claude responded: They're independent buckets — with one shared bucket on top.
Claude responded: They're independent buckets — with one shared bucket on top.
Analyzed independent rate limit buckets and their practical interactions
Analyzed independent rate limit buckets and their practical interactions
They're independent buckets — with one shared bucket on top.
The three buckets and what each call hits
The three buckets and what each call hits
Copy to clipboard
┌──────────────────┐
Search request ──→ │ Search: 5/sec │ ──┐
└──────────────────┘ │
├──→ ┌─────────────────┐
┌──────────────────┐ │ │ Daily: 250k–1M │
Non-search call ──→ │ Burst: 190/10s │ ──┘ │ (per portal) │
└──────────────────┘ └─────────────────┘
A search call is only metered against the search bucket and the daily bucket. A non-search call (batch read/update, single PATCH, associations, etc.) is only metered against the burst bucket and the daily bucket. The two short-window buckets do not share counters.
What this means practically
What this means practically
Hitting search secondly limit (5/s):
Only further
/search
calls 429. Your batch reads, batch updates, single PATCHes, association calls — all keep working at full burst speed. This is actually useful: if your sync is bottlenecked on Search, you can pivot to using
lastmodifieddate
filters via batch endpoints, or use the IDs you already have to do batch reads, while Search cools off.
Hitting burst limit (190/10s):
Only non-search calls 429. You can still issue Search calls at 5/s. Useful for: continuing to identify deltas for queueing while in-flight updates drain, or refreshing a small set of records via Search even though your write pipeline is paused.
Hitting daily limit:
Everything stops. Search and non-search alike. Doesn't unblock until midnight in your portal's configured timezone — and remember this is shared across every private app in the portal, plus n8n flows, marketing tools, anything else hitting the API with that account.
So can one type of request block the other?
So can one type of request block the other?
Search → Burst:
No.
Saturating Search at 50 calls per 10s leaves your full 190/10s burst untouched.
Burst → Search:
No.
Saturating burst leaves Search's 5/s untouched.
Either → Daily:
Yes
, but only by contributing to the same daily counter. It's volume that kills you here, not the type.
In theory you can sustain ~50 search + ~190 other =
~240 calls per 10 seconds
indefinitely (until daily runs out), because the two buckets bill independently.
Implementation consequence
Implementation consequence
Your rate limiter needs to know which bucket a request hits before it acquires. Cleanest pattern:
Copy to clipboard
php
$limiter
->
acquire
(
'search'
,
$weight
=
1
)
;
// for search endpoints only
$limiter
->
acquire
(
'burst'
,
$weight
=
1
)
;
// for everything else
$limiter
->
acquire
(
'daily'
,
$weight
=
1
)
;
// every call, both kinds
In Redis: three separate keys, three separate Lua acquire scripts (or one script with a bucket parameter). A search call calls
acquire('search')
+
acquire('daily')
. A batch update calls
acquire('burst')
+
acquire('daily')
.
One subtle pitfall: when you backoff on a 429,
inspect
policyName
in the response body
to know which bucket actually fired. If you see
SECONDLY
from a search endpoint, you only need to delay search-bound jobs — burst-bound jobs in the queue can keep running. If you blanket-pause everything on any 429, you waste capacity on the bucket that's still healthy. Two queues (or two throttle keys) make this clean; one global pause is the lazy version.
The other subtlety: the burst response gives you
X-HubSpot-RateLimit-Remaining
to clamp local state against, but search doesn't return those headers. So your search counter is unverified — be slightly more conservative there (e.g., budget 4/s instead of 5) to absorb the unaccounted-for calls.
Copy
Give positive feedback
Give negative feedback
Retry
You said: Ok, so what will happen each time I make a request?
You said: Ok, so what will happen each time I make a request?
Ok, so what will happen each time I make a request? Let's say I have 100,000 requests to make that are instant. Do I need to increment each request based on the type? For example, if there is a search request, I need to increment both the search bucket and also the daily bucket. If it's a burst, then I can go to the daily and burst buckets. If I need to check if it can make a call, do I need to see both the daily and search, or burst, respectively? Isn't that too heavy for the infrastructure, adding additional load to each request?
13:44
Retry
Edit
Copy
Claude responded: Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out.
Claude responded: Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out.
Analyzed per-request overhead concerns and quantified Redis performance impact
Analyzed per-request overhead concerns and quantified Redis performance impact
Yes, your understanding is correct — every request must check and reserve from each bucket it applies to, atomically, before the call goes out. But the overhead is much smaller than it sounds, and importantly, it's nowhere near your bottleneck....
|
NULL
|
NULL
|
NULL
|
NULL
|
|
26426
|
1094
|
19
|
2026-05-12T12:28:28.241362+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778588908241_m1.jpg...
|
Claude
|
Claude
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Skip to content
Skip to content
Click to collapse
Skip to content
Skip to content
Click to collapse
⌘B
Drag to resize
Collapse sidebar
Search
Chat
Cowork
Code
New chat ⌘N
New chat
⌘N
Projects
Artifacts
Customize
Pinned
Bulgarian citizenship application process for EU residents
More options for Bulgarian citizenship application process for EU residents
Dawarich location tracking project
More options for Dawarich location tracking project
Recents
View all
Screenpipe data sync and retention management
More options for Screenpipe data sync and retention management
Screenpipe sync script failing after recent migrations
More options for Screenpipe sync script failing after recent migrations
Hubspot BadRequest headers debugging
More options for Hubspot BadRequest headers debugging
Monthly expense tracking
More options for Monthly expense tracking
Exporting transaction data from Notion to finance hub
More options for Exporting transaction data from Notion to finance hub
💬 How much have I spent for groc…
More options for 💬 How much have I spent for groc…
April 2026 spending by category
More options for April 2026 spending by category
Code diff review
More options for Code diff review
HubSpot rate limit implementation strategy
More options for HubSpot rate limit implementation strategy
Screenpipe retention policy code location
More options for Screenpipe retention policy code location
Viewing retention policy in screenpipe
More options for Viewing retention policy in screenpipe
Clean shot x video recording termination issue
More options for Clean shot x video recording termination issue
HubSpot rate limit handling with executeRequest
More options for HubSpot rate limit handling with executeRequest
Untitled
More options
💬 Screen pipe. Is there ability…
More options for 💬 Screen pipe. Is there ability…
SMB mount access inconsistency between Finder and iTerm
More options for SMB mount access inconsistency between Finder and iTerm
💬 What is the best switch I can…
More options for 💬 What is the best switch I can…
Permission denied on screenpipe volume
More options for Permission denied on screenpipe volume
Screenpipe sync database attachment error
More options for Screenpipe sync database attachment error
Last swimming outing with Dani
More options for Last swimming outing with Dani
Lukas Pro
Get apps and extensions
Screenpipe data sync and retention management, rename chat
Screenpipe data sync and retention management
More options for Screenpipe data sync and retention management
Close
Share chat
Claude finished the response
You said: Lets start from the beginning with the fresh mind.
You said: Lets start from the beginning with the fresh mind.
Pasted Text, pasted, 495 lines
#!/bin/bash # screenpipe_sync.sh # Syncs Screenpipe SQLite data to a NAS archive database (append-only, no deletions). # Also copies the day's video/frame data folder to the NAS. # # Schema-drift tolerant: if Screenpipe migrations add new columns to the source DB, # the NAS archive gets ALTER TABLE'
PASTED
Lets start from the beginning with the fresh mind. There is a script for screenpipe to copy data for day from mac to nas. There are two issues I want to work with. Firsts if I reinstall the mac version it starts from fresh id 1. That causes some issues. How to make sure the data are valid. I don't want some overcomplicated flow. I was thinking about making new db every 3 months. Secodn issue is that I wan to implement cleanup (retention policy) on mac original screenpipe db. I want script that will remove data that are 7 days old or older for example. ANd lastly I want to extedn the script to work with audio as well. What od you need
20:19
Retry
Edit
Copy
Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…
Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…
Analyzed three technical challenges and identified clarifying questions needed
Analyzed three technical challenges and identified clarifying questions needed
Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether reinstalls have already happened). Before I touch the script, a few things:
Issue 1 — ID collisions / archive rotation
Has a reinstall already happened, or is the current
archive.db
still from one continuous install? If collisions already exist I need to handle that first; if not, we have a clean slate.
Quarterly rotation works, but it doesn't actually solve reinstalls
within
a quarter. A cleaner option that I'd lean toward: add an
install_id
column (UUID generated once and stored in a tiny...
|
[{"role":"AXLink","text":& [{"role":"AXLink","text":"Skip to content","depth":14,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Skip to content","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Click to collapse","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"⌘B","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drag to resize","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Collapse sidebar","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cowork","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New chat ⌘N","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New chat","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"⌘N","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Projects","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Artifacts","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pinned","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Bulgarian citizenship application process for EU residents","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Bulgarian citizenship application process for EU residents","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Dawarich location tracking project","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Dawarich location tracking project","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Recents","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"View all","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe data sync and retention management","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe data sync and retention management","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync script failing after recent migrations","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe sync script failing after recent migrations","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hubspot BadRequest headers debugging","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Hubspot BadRequest headers debugging","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Monthly expense tracking","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Monthly expense tracking","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Exporting transaction data from Notion to finance hub","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Exporting transaction data from Notion to finance hub","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 How much have I spent for groc…","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 How much have I spent for groc…","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"April 2026 spending by category","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for April 2026 spending by category","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code diff review","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Code diff review","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit implementation strategy","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit implementation strategy","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe retention policy code location","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe retention policy code location","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Viewing retention policy in screenpipe","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Viewing retention policy in screenpipe","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Clean shot x video recording termination issue","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Clean shot x video recording termination issue","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit handling with executeRequest","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit handling with executeRequest","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Untitled","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 Screen pipe. Is there ability…","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 Screen pipe. Is there ability…","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"SMB mount access inconsistency between Finder and iTerm","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for SMB mount access inconsistency between Finder and iTerm","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 What is the best switch I can…","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 What is the best switch I can…","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Permission denied on screenpipe volume","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Permission denied on screenpipe volume","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync database attachment error","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe sync database attachment error","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Last swimming outing with Dani","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Last swimming outing with Dani","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Lukas Pro","depth":15,"bounds":{"left":0.49097222,"top":0.0,"width":0.08055556,"height":0.026666667},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Get apps and extensions","depth":15,"bounds":{"left":0.6576389,"top":0.0,"width":0.016666668,"height":0.026666667},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe data sync and retention management, rename chat","depth":19,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Screenpipe data sync and retention management","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"More options for Screenpipe data sync and retention management","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Share chat","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Claude finished the response","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"You said: Lets start from the beginning with the fresh mind.","depth":20,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: Lets start from the beginning with the fresh mind.","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Pasted Text, pasted, 495 lines","depth":21,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#!/bin/bash # screenpipe_sync.sh # Syncs Screenpipe SQLite data to a NAS archive database (append-only, no deletions). # Also copies the day's video/frame data folder to the NAS. # # Schema-drift tolerant: if Screenpipe migrations add new columns to the source DB, # the NAS archive gets ALTER TABLE'","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PASTED","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Lets start from the beginning with the fresh mind. There is a script for screenpipe to copy data for day from mac to nas. There are two issues I want to work with. Firsts if I reinstall the mac version it starts from fresh id 1. That causes some issues. How to make sure the data are valid. I don't want some overcomplicated flow. I was thinking about making new db every 3 months. Secodn issue is that I wan to implement cleanup (retention policy) on mac original screenpipe db. I want script that will remove data that are 7 days old or older for example. ANd lastly I want to extedn the script to work with audio as well. What od you need","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20:19","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…","depth":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Analyzed three technical challenges and identified clarifying questions needed","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzed three technical challenges and identified clarifying questions needed","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether reinstalls have already happened). Before I touch the script, a few things:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Issue 1 — ID collisions / archive rotation","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Has a reinstall already happened, or is the current","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"archive.db","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"still from one continuous install? If collisions already exist I need to handle that first; if not, we have a clean slate.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Quarterly rotation works, but it doesn't actually solve reinstalls","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"within","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"a quarter. A cleaner option that I'd lean toward: add an","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"install_id","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"column (UUID generated once and stored in a tiny","depth":26,"on_screen":false,"role_description":"text"}]...
|
-9077209816799628969
|
5773543863664335445
|
click
|
accessibility
|
NULL
|
Skip to content
Skip to content
Click to collapse
Skip to content
Skip to content
Click to collapse
⌘B
Drag to resize
Collapse sidebar
Search
Chat
Cowork
Code
New chat ⌘N
New chat
⌘N
Projects
Artifacts
Customize
Pinned
Bulgarian citizenship application process for EU residents
More options for Bulgarian citizenship application process for EU residents
Dawarich location tracking project
More options for Dawarich location tracking project
Recents
View all
Screenpipe data sync and retention management
More options for Screenpipe data sync and retention management
Screenpipe sync script failing after recent migrations
More options for Screenpipe sync script failing after recent migrations
Hubspot BadRequest headers debugging
More options for Hubspot BadRequest headers debugging
Monthly expense tracking
More options for Monthly expense tracking
Exporting transaction data from Notion to finance hub
More options for Exporting transaction data from Notion to finance hub
💬 How much have I spent for groc…
More options for 💬 How much have I spent for groc…
April 2026 spending by category
More options for April 2026 spending by category
Code diff review
More options for Code diff review
HubSpot rate limit implementation strategy
More options for HubSpot rate limit implementation strategy
Screenpipe retention policy code location
More options for Screenpipe retention policy code location
Viewing retention policy in screenpipe
More options for Viewing retention policy in screenpipe
Clean shot x video recording termination issue
More options for Clean shot x video recording termination issue
HubSpot rate limit handling with executeRequest
More options for HubSpot rate limit handling with executeRequest
Untitled
More options
💬 Screen pipe. Is there ability…
More options for 💬 Screen pipe. Is there ability…
SMB mount access inconsistency between Finder and iTerm
More options for SMB mount access inconsistency between Finder and iTerm
💬 What is the best switch I can…
More options for 💬 What is the best switch I can…
Permission denied on screenpipe volume
More options for Permission denied on screenpipe volume
Screenpipe sync database attachment error
More options for Screenpipe sync database attachment error
Last swimming outing with Dani
More options for Last swimming outing with Dani
Lukas Pro
Get apps and extensions
Screenpipe data sync and retention management, rename chat
Screenpipe data sync and retention management
More options for Screenpipe data sync and retention management
Close
Share chat
Claude finished the response
You said: Lets start from the beginning with the fresh mind.
You said: Lets start from the beginning with the fresh mind.
Pasted Text, pasted, 495 lines
#!/bin/bash # screenpipe_sync.sh # Syncs Screenpipe SQLite data to a NAS archive database (append-only, no deletions). # Also copies the day's video/frame data folder to the NAS. # # Schema-drift tolerant: if Screenpipe migrations add new columns to the source DB, # the NAS archive gets ALTER TABLE'
PASTED
Lets start from the beginning with the fresh mind. There is a script for screenpipe to copy data for day from mac to nas. There are two issues I want to work with. Firsts if I reinstall the mac version it starts from fresh id 1. That causes some issues. How to make sure the data are valid. I don't want some overcomplicated flow. I was thinking about making new db every 3 months. Secodn issue is that I wan to implement cleanup (retention policy) on mac original screenpipe db. I want script that will remove data that are 7 days old or older for example. ANd lastly I want to extedn the script to work with audio as well. What od you need
20:19
Retry
Edit
Copy
Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…
Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…
Analyzed three technical challenges and identified clarifying questions needed
Analyzed three technical challenges and identified clarifying questions needed
Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether reinstalls have already happened). Before I touch the script, a few things:
Issue 1 — ID collisions / archive rotation
Has a reinstall already happened, or is the current
archive.db
still from one continuous install? If collisions already exist I need to handle that first; if not, we have a clean slate.
Quarterly rotation works, but it doesn't actually solve reinstalls
within
a quarter. A cleaner option that I'd lean toward: add an
install_id
column (UUID generated once and stored in a tiny...
|
26425
|
NULL
|
NULL
|
NULL
|
|
26455
|
1094
|
30
|
2026-05-12T12:29:34.812339+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778588974812_m1.jpg...
|
Claude
|
Claude
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Skip to content
Skip to content
Click to collapse
Skip to content
Skip to content
Click to collapse
⌘B
Drag to resize
Collapse sidebar
Search
Chat
Cowork
Code
New chat ⌘N
New chat
⌘N
Projects
Artifacts
Customize
Pinned
Bulgarian citizenship application process for EU residents
More options for Bulgarian citizenship application process for EU residents
Dawarich location tracking project
More options for Dawarich location tracking project
Recents
View all
Screenpipe data sync and retention management
More options for Screenpipe data sync and retention management
Screenpipe sync script failing after recent migrations
More options for Screenpipe sync script failing after recent migrations
Hubspot BadRequest headers debugging
More options for Hubspot BadRequest headers debugging
Monthly expense tracking
More options for Monthly expense tracking
Exporting transaction data from Notion to finance hub
More options for Exporting transaction data from Notion to finance hub
💬 How much have I spent for groc…
More options for 💬 How much have I spent for groc…
April 2026 spending by category
More options for April 2026 spending by category
Code diff review
More options for Code diff review
HubSpot rate limit implementation strategy
More options for HubSpot rate limit implementation strategy
Screenpipe retention policy code location
More options for Screenpipe retention policy code location
Viewing retention policy in screenpipe
More options for Viewing retention policy in screenpipe
Clean shot x video recording termination issue
More options for Clean shot x video recording termination issue
HubSpot rate limit handling with executeRequest
More options for HubSpot rate limit handling with executeRequest
Untitled
More options
💬 Screen pipe. Is there ability…
More options for 💬 Screen pipe. Is there ability…
SMB mount access inconsistency between Finder and iTerm
More options for SMB mount access inconsistency between Finder and iTerm
💬 What is the best switch I can…
More options for 💬 What is the best switch I can…
Permission denied on screenpipe volume
More options for Permission denied on screenpipe volume
Screenpipe sync database attachment error
More options for Screenpipe sync database attachment error
Last swimming outing with Dani
More options for Last swimming outing with Dani
Lukas Pro
Get apps and extensions
Screenpipe data sync and retention management, rename chat
Screenpipe data sync and retention management
More options for Screenpipe data sync and retention management
Close
Share chat
Claude finished the response
You said: Lets start from the beginning with the fresh mind.
You said: Lets start from the beginning with the fresh mind.
Pasted Text, pasted, 495 lines
#!/bin/bash # screenpipe_sync.sh # Syncs Screenpipe SQLite data to a NAS archive database (append-only, no deletions). # Also copies the day's video/frame data folder to the NAS. # # Schema-drift tolerant: if Screenpipe migrations add new columns to the source DB, # the NAS archive gets ALTER TABLE'
PASTED
Lets start from the beginning with the fresh mind. There is a script for screenpipe to copy data for day from mac to nas. There are two issues I want to work with. Firsts if I reinstall the mac version it starts from fresh id 1. That causes some issues. How to make sure the data are valid. I don't want some overcomplicated flow. I was thinking about making new db every 3 months. Secodn issue is that I wan to implement cleanup (retention policy) on mac original screenpipe db. I want script that will remove data that are 7 days old or older for example. ANd lastly I want to extedn the script to work with audio as well. What od you need
20:19
Retry
Edit
Copy
Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…
Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…
Analyzed three technical challenges and identified clarifying questions needed
Analyzed three technical challenges and identified clarifying questions needed
Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether reinstalls have already happened). Before I touch the script, a few things:
Issue 1 — ID collisions / archive rotation
Has a reinstall already happened, or is the current
archive.db
still from one continuous install? If collisions already exist I need to handle that first; if not, we have a clean slate.
Quarterly rotation works, but it doesn't actually solve reinstalls
within
a quarter. A cleaner option that I'd lean toward: add an
install_id
column (UUID generated once and stored in a tiny...
|
[{"role":"AXLink","text":& [{"role":"AXLink","text":"Skip to content","depth":14,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Skip to content","depth":15,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Click to collapse","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"⌘B","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drag to resize","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Collapse sidebar","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cowork","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New chat ⌘N","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New chat","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"⌘N","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Projects","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Artifacts","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Customize","depth":15,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pinned","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Bulgarian citizenship application process for EU residents","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Bulgarian citizenship application process for EU residents","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Dawarich location tracking project","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Dawarich location tracking project","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Recents","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"View all","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe data sync and retention management","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe data sync and retention management","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync script failing after recent migrations","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe sync script failing after recent migrations","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hubspot BadRequest headers debugging","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Hubspot BadRequest headers debugging","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Monthly expense tracking","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Monthly expense tracking","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Exporting transaction data from Notion to finance hub","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Exporting transaction data from Notion to finance hub","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 How much have I spent for groc…","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 How much have I spent for groc…","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"April 2026 spending by category","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for April 2026 spending by category","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code diff review","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Code diff review","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit implementation strategy","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit implementation strategy","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe retention policy code location","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe retention policy code location","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Viewing retention policy in screenpipe","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Viewing retention policy in screenpipe","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Clean shot x video recording termination issue","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Clean shot x video recording termination issue","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"HubSpot rate limit handling with executeRequest","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for HubSpot rate limit handling with executeRequest","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Untitled","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 Screen pipe. Is there ability…","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 Screen pipe. Is there ability…","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"SMB mount access inconsistency between Finder and iTerm","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for SMB mount access inconsistency between Finder and iTerm","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"💬 What is the best switch I can…","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for 💬 What is the best switch I can…","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Permission denied on screenpipe volume","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Permission denied on screenpipe volume","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe sync database attachment error","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Screenpipe sync database attachment error","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Last swimming outing with Dani","depth":18,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More options for Last swimming outing with Dani","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Lukas Pro","depth":15,"bounds":{"left":0.49097222,"top":0.0,"width":0.08055556,"height":0.026666667},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Get apps and extensions","depth":15,"bounds":{"left":0.6576389,"top":0.0,"width":0.016666668,"height":0.026666667},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Screenpipe data sync and retention management, rename chat","depth":19,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Screenpipe data sync and retention management","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"More options for Screenpipe data sync and retention management","depth":19,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Share chat","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Claude finished the response","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"You said: Lets start from the beginning with the fresh mind.","depth":20,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"You said: Lets start from the beginning with the fresh mind.","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Pasted Text, pasted, 495 lines","depth":21,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#!/bin/bash # screenpipe_sync.sh # Syncs Screenpipe SQLite data to a NAS archive database (append-only, no deletions). # Also copies the day's video/frame data folder to the NAS. # # Schema-drift tolerant: if Screenpipe migrations add new columns to the source DB, # the NAS archive gets ALTER TABLE'","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PASTED","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Lets start from the beginning with the fresh mind. There is a script for screenpipe to copy data for day from mac to nas. There are two issues I want to work with. Firsts if I reinstall the mac version it starts from fresh id 1. That causes some issues. How to make sure the data are valid. I don't want some overcomplicated flow. I was thinking about making new db every 3 months. Secodn issue is that I wan to implement cleanup (retention policy) on mac original screenpipe db. I want script that will remove data that are 7 days old or older for example. ANd lastly I want to extedn the script to work with audio as well. What od you need","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"20:19","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Retry","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…","depth":21,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…","depth":22,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Analyzed three technical challenges and identified clarifying questions needed","depth":22,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzed three technical challenges and identified clarifying questions needed","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether reinstalls have already happened). Before I touch the script, a few things:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Issue 1 — ID collisions / archive rotation","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Has a reinstall already happened, or is the current","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"archive.db","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"still from one continuous install? If collisions already exist I need to handle that first; if not, we have a clean slate.","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Quarterly rotation works, but it doesn't actually solve reinstalls","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"within","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"a quarter. A cleaner option that I'd lean toward: add an","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"install_id","depth":27,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"column (UUID generated once and stored in a tiny","depth":26,"on_screen":false,"role_description":"text"}]...
|
-9077209816799628969
|
5773543863664335445
|
click
|
accessibility
|
NULL
|
Skip to content
Skip to content
Click to collapse
Skip to content
Skip to content
Click to collapse
⌘B
Drag to resize
Collapse sidebar
Search
Chat
Cowork
Code
New chat ⌘N
New chat
⌘N
Projects
Artifacts
Customize
Pinned
Bulgarian citizenship application process for EU residents
More options for Bulgarian citizenship application process for EU residents
Dawarich location tracking project
More options for Dawarich location tracking project
Recents
View all
Screenpipe data sync and retention management
More options for Screenpipe data sync and retention management
Screenpipe sync script failing after recent migrations
More options for Screenpipe sync script failing after recent migrations
Hubspot BadRequest headers debugging
More options for Hubspot BadRequest headers debugging
Monthly expense tracking
More options for Monthly expense tracking
Exporting transaction data from Notion to finance hub
More options for Exporting transaction data from Notion to finance hub
💬 How much have I spent for groc…
More options for 💬 How much have I spent for groc…
April 2026 spending by category
More options for April 2026 spending by category
Code diff review
More options for Code diff review
HubSpot rate limit implementation strategy
More options for HubSpot rate limit implementation strategy
Screenpipe retention policy code location
More options for Screenpipe retention policy code location
Viewing retention policy in screenpipe
More options for Viewing retention policy in screenpipe
Clean shot x video recording termination issue
More options for Clean shot x video recording termination issue
HubSpot rate limit handling with executeRequest
More options for HubSpot rate limit handling with executeRequest
Untitled
More options
💬 Screen pipe. Is there ability…
More options for 💬 Screen pipe. Is there ability…
SMB mount access inconsistency between Finder and iTerm
More options for SMB mount access inconsistency between Finder and iTerm
💬 What is the best switch I can…
More options for 💬 What is the best switch I can…
Permission denied on screenpipe volume
More options for Permission denied on screenpipe volume
Screenpipe sync database attachment error
More options for Screenpipe sync database attachment error
Last swimming outing with Dani
More options for Last swimming outing with Dani
Lukas Pro
Get apps and extensions
Screenpipe data sync and retention management, rename chat
Screenpipe data sync and retention management
More options for Screenpipe data sync and retention management
Close
Share chat
Claude finished the response
You said: Lets start from the beginning with the fresh mind.
You said: Lets start from the beginning with the fresh mind.
Pasted Text, pasted, 495 lines
#!/bin/bash # screenpipe_sync.sh # Syncs Screenpipe SQLite data to a NAS archive database (append-only, no deletions). # Also copies the day's video/frame data folder to the NAS. # # Schema-drift tolerant: if Screenpipe migrations add new columns to the source DB, # the NAS archive gets ALTER TABLE'
PASTED
Lets start from the beginning with the fresh mind. There is a script for screenpipe to copy data for day from mac to nas. There are two issues I want to work with. Firsts if I reinstall the mac version it starts from fresh id 1. That causes some issues. How to make sure the data are valid. I don't want some overcomplicated flow. I was thinking about making new db every 3 months. Secodn issue is that I wan to implement cleanup (retention policy) on mac original screenpipe db. I want script that will remove data that are 7 days old or older for example. ANd lastly I want to extedn the script to work with audio as well. What od you need
20:19
Retry
Edit
Copy
Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…
Claude responded: Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether…
Analyzed three technical challenges and identified clarifying questions needed
Analyzed three technical challenges and identified clarifying questions needed
Good plan to tackle these together — they interact (retention timing depends on sync timing, audio sync depends on schema shape, ID strategy depends on whether reinstalls have already happened). Before I touch the script, a few things:
Issue 1 — ID collisions / archive rotation
Has a reinstall already happened, or is the current
archive.db
still from one continuous install? If collisions already exist I need to handle that first; if not, we have a clean slate.
Quarterly rotation works, but it doesn't actually solve reinstalls
within
a quarter. A cleaner option that I'd lean toward: add an
install_id
column (UUID generated once and stored in a tiny...
|
26453
|
NULL
|
NULL
|
NULL
|
|
10891
|
489
|
12
|
2026-05-08T18:05:45.363887+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-08/1778 /Users/lukas/.screenpipe/data/data/2026-05-08/1778263545363_m1.jpg...
|
Code
|
Review payment logger au… — docker [SSH: nas]
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 55 pending changes
55
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: docker [SSH: nas]
Explorer Section: docker [SSH: nas]
DOCKER [SSH: NAS]
adguard
ai-stack
app-db
appflowy
audiobookshelf
auth
beszel
bitwarden
dawarich
dsk-uploader
finance
payments-logger
flask-app
garmin-connector
gitea
health
health-tracker
homarr
hst
immich
jellyfinht
kavita
libreoffice
linkwarden
location-logger
alembic
app
mcp-server
.env
.env.example
.gitignore
.mcp.json
M
alembic.ini
docker-compose.yml
M
Dockerfile
README.md
M
requirements.txt
M
today_map.html
mariadb
meeting-detector
mindfulmama
n8n
notifier-app
npm
oauth
obsidian
ollama
open-webui
openttd
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
docker-compose.yml, Editor Group 1
docker-compose.yml, Editor Group 1
services:
postgresql:
image: docker.io/library/postgres:16-alpine
container_name: Authentik-DB
hostname: authentik-db
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}"]
interval: 5s
timeout: 5s
retries: 5
environment:
POSTGRES_PASSWORD: [PASSWORD]
POSTGRES_USER: authentik
POSTGRES_DB: authentik
volumes:
- /volume2/docker/auth/db:/var/lib/postgresql/data
networks:
- authentik_internal
redis:
image: docker.io/library/redis:alpine
container_name: Authentik-REDIS
hostname: authentik-redis
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 5s
timeout: 3s
retries: 5
networks:
- authentik_internal
server:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}
container_name: Authentik-Server
hostname: authentik-server
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: [PASSWORD]
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
AUTHENTIK_HOST: ${AUTHENTIK_HOST}
AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}
AUTHENTIK_BOOTSTRAP_PASSWORD: [PASSWORD]
ports:
- "9100:9000"
volumes:
- /volume2/docker/auth/media:/media
- /volume2/docker/auth/templates:/templates
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- authentik_internal
- proxy
worker:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}
container_name: Authentik-Worker
hostname: authentik-worker
restart: unless-stopped
command: worker
user: root
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: [PASSWORD]
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /volume2/docker/auth/media:/media
- /volume2/docker/auth/certs:/certs
- /volume2/docker/auth/templates:/templates
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- authentik_internal
outpost:
image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}
container_name: Authentik-Outpost
hostname: authentik-outpost
restart: unless-stopped
environment:
AUTHENTIK_HOST: ${AUTHENTIK_HOST}
AUTHENTIK_INSECURE: "false"
AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}
ports:
- "9101:9000"
depends_on:
- server
networks:
- authentik_internal
- proxy
networks:
authentik_internal:
internal: true
proxy:
external: true
services:
postgresql:
image: docker.io/library/postgres:16-alpine
container_name: Authentik-DB
hostname: authentik-db
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}"]
interval: 5s
timeout: 5s
retries: 5
environment:
POSTGRES_PASSWORD: [PASSWORD]
POSTGRES_USER: authentik
POSTGRES_DB: authentik
volumes:
- /volume2/docker/auth/db:/var/lib/postgresql/data
networks:
- authentik_internal
redis:
image: docker.io/library/redis:alpine
container_name: Authentik-REDIS
hostname: authentik-redis
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 5s
timeout: 3s
retries: 5
networks:
- authentik_internal
server:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}
container_name: Authentik-Server
hostname: authentik-server
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: [PASSWORD]
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
AUTHENTIK_HOST: ${AUTHENTIK_HOST}
AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}
AUTHENTIK_BOOTSTRAP_PASSWORD: [PASSWORD]
ports:
- "9100:9000"
volumes:
- /volume2/docker/auth/media:/media
- /volume2/docker/auth/templates:/templates
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- authentik_internal
- proxy
worker:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}
container_name: Authentik-Worker
hostname: authentik-worker
restart: unless-stopped
command: worker
user: root
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: [PASSWORD]
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /volume2/docker/auth/media:/media
- /volume2/docker/auth/certs:/certs
- /volume2/docker/auth/templates:/templates
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- authentik_internal
outpost:
image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}
container_name: Authentik-Outpost
hostname: authentik-outpost
restart: unless-stopped
environment:
AUTHENTIK_HOST: ${AUTHENTIK_HOST}
AUTHENTIK_INSECURE: "false"
AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}
ports:
- "9101:9000"
depends_on:
- server
networks:
- authentik_internal
- proxy
networks:
authentik_internal:
internal: true
proxy:
external: true
Review payment logger au…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: nas
SSH: nas
location-logger (Git)
location-logger
location-logger (Git) - main*, Checkout Branch/Tag...
main*
location-logger (Git) - Synchronize Changes
No Problems
0
0
No Ports Forwarded
0
Notifications
Sign In
Sign In
collapsed
Command Succeeded
Review payment logger authorization implementation
Session history
New session
Message actions
review payment_logger project how toes authorization work
Thinking
Thinking
Let me explore the payment_logger project structure first.
Bash
Find payment_logger project files
IN
find /volume2/docker -type f -name "*.py" -o -name "*.yml" -o -name "*.yaml" -o -name "*.env" -o -name "*.toml" -o -name "*.cfg" | grep -i payment | head -50
Copy code to clipboard
OUT
bfs: error: /volume2/docker/portnotedb/pg_commit_ts: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_dynshmem: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_notify: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_serial: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_snapshots: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_subtrans: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_twophase: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_multixact: Permission denied.
bfs: error: /volume2/docker/portnotedb/base: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_replslot: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_tblspc: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_stat: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_stat_tmp: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_xact: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_logical: Permission denied.
bfs: error: /volume2/docker/openttd/.dbus: Permission denied.
bfs: error: /volume2/docker/immich/db: Permission denied.
bfs: error: /volume2/docker/paperlessngx/db: Permission denied.
bfs: error: /volume2/docker/appflowy/postgres: Permission denied.
bfs: error: /volume2/docker/auth/db: Permission denied.
bfs: error: /volume2/docker/openttd/.XDG/dbus-1: Permission denied.
bfs: error: /volume2/docker/openttd/.config/pulse: Permission denied.
bfs: error: /volume2/docker/openttd/.cache/openbox/sessions: Permission denied.
/volume2/docker/payments-logger/.env
/volume2/docker/payments-logger/docker-compose.yml
/volume2/docker/payments-logger/backend/prisma/migrations/migration_lock.toml
Bash
List docker directory contents
IN
ls /volume2/docker/
Copy code to clipboard
OUT
adguard
ai-stack
app-db
appflowy
audiobookshelf
auth
beszel
bitwarden
dawarich
dsk-uploader
flask-app
garmin-connector
gitea
health
health-tracker
homarr
hst
immich
jellyfinht
kavita
libreoffice
linkwarden
location-logger
mariadb
meeting-detector
mindfulmama
n8n
notifier-app
npm
oauth
obsidian
ollama
openttd
openvpn-client
open-webui
orchestrator
outfit-app
owntracks-stack
paperlessngx
payments-logger
personal-log
personal-log-system
player
portainer
portnotedb
reminders-app
romm
second-brain
static
stirling
syncthing
tailscale
temp-logger
test-app
tmp
torrent-stack
tree
trilium
tubearchivist
twenty
uptimekuma
ytptube
Agent:
Explore payment_logger authorization code
IN
Explore the payments-logger project at /volume2/docker/payments-logger and give me a thorough understanding of how authorization works. I need to know:
1. What auth mechanism is used (JWT, sessions, API keys, OAuth, etc.)
2. Where auth is enforced (middleware, decorators, route guards, etc.)
3. What roles/permissions exist
4. How tokens are issued, validated, and refreshed
5. Any auth-related config (env vars, settings)
Please read the key source files and give me a clear summary with file paths and line numbers for the important parts.
Bash
IN
find /volume2/docker/payments-logger -type f -name "*.py" -o -name "*.json" -o -name "*.yml" -o -name "*.yaml" | grep -E "(auth|token|jwt|session|permission|role)" | head -20
Copy code to clipboard
OUT
(Bash completed with no output)
Bash
IN
ls -la /volume2/docker/payments-logger/ 2>/dev/null || echo "Directory not found"
Copy code to clipboard
OUT
total 36
drwxrwxrwx 1 Adm1n admin 162 Mar 29 18:01 .
drwxrwxrwx 1 root root 1146 Apr 26 18:49 ..
-rwxrwxrwx 1 Adm1n admin 15233 Feb 22 17:08 API.md
drwxrwxrwx 1 Adm1n admin 88 Mar 29 15:41 backend
drwxrwxrwx 1 Adm1n admin 38 Mar 29 17:07 .claude
-rwxrwxrwx 1 Adm1n admin 1502 Mar 29 18:01 docker-compose.yml
-rwxrwxrwx 1 Adm1n admin 1066 Mar 29 15:44 .env
-rwxrwxrwx 1 Adm1n admin 1078 Feb 14 17:53 .env.example
drwxrwxrwx 1 Adm1n admin 194 Mar 29 15:44 frontend
-rwxrwxrwx 1 Adm1n admin 19 Feb 14 17:54 .gitignore
-rwxrwxrwx 1 Adm1n admin 4052 Feb 14 19:06 README.md
Bash
IN
find /volume2/docker/payments-logger/backend -type f | head -30
Copy code to clipboard
OUT
/volume2/docker/payments-logger/backend/Dockerfile
/volume2/docker/payments-logger/backend/.dockerignore
/volume2/docker/payments-logger/backend/package.json
/volume2/docker/payments-logger/backend/prisma/schema.prisma
/volume2/docker/payments-logger/backend/src/parser.js
/volume2/docker/payments-logger/backend/src/index.js
/volume2/docker/payments-logger/backend/src/auth.js
/volume2/docker/payments-logger/backend/prisma/migrations/migration_lock.toml
/volume2/docker/payments-logger/backend/src/routes/payments.js
/volume2/docker/payments-logger/backend/prisma/migrations/20260210_init/migration.sql
/volume2/docker/payments-logger/backend/prisma/migrations/20260210_simplify/migration.sql
/volume2/docker/payments-logger/backend/prisma/migrations/20260222_add_card/migration.sql
Bash
IN
find /volume2/docker/payments-logger -type f \( -name "*.js" -o -name "*.json" -o -name "*.md" \) | sort
Copy code to clipboard
OUT
/volume2/docker/payments-logger/API.md
/volume2/docker/payments-logger/backend/package.json
/volume2/docker/payments-logger/backend/src/auth.js
/volume2/docker/payments-logger/backend/src/index.js
/volume2/docker/payments-logger/backend/src/parser.js
/volume2/docker/payments-logger/backend/src/routes/payments.js
/volume2/docker/payments-logger/.claude/settings.local.json
/volume2/docker/payments-logger/frontend/package.json
/volume2/docker/payments-logger/frontend/postcss.config.js
/volume2/docker/payments-logger/frontend/src/auth.js
/volume2/docker/payments-logger/frontend/tailwind.config.js
/volume2/docker/payments-logger/frontend/vite.config.js
/volume2/docker/payments-logger/README.md
Read
.env
.env
Read
auth.js
auth.js
Read
index.js
index.js
Read
package.json
package.json
Read
auth.js
auth.js
Read
API.md
API.md
Read
payments.js
payments.js
Read
.env.example
.env.example
Read
schema.prisma
schema.prisma
Bash
IN
grep -r "API_KEY\|auth\|token\|oauth\|hydra" /volume2/docker/payments-logger/backend/src --include="*.js" -n
Copy code to clipboard
OUT
/volume2/docker/payments-logger/backend/src/index.js:6:const { bearerTokenMiddleware, wellKnownRouter } = require('./auth');
/volume2/docker/payments-logger/backend/src/index.js:18:// ── OAuth Bearer token auth (skips public paths) ──────────────────────────────
/volume2/docker/payments-logger/backend/src/auth.js:2: * OAuth 2.1 / Hydra JWT authentication for Express.
/volume2/docker/payments-logger/backend/src/auth.js:6: * - wellKnownRouter — serves /.well-known/oauth-* discovery endpoints
/volume2/docker/payments-logger/backend/src/auth.js:33:function sendUnauthorized(res, detail, error = 'invalid_token') {
/volume2/docker/payments-logger/backend/src/auth.js:39: `resource_metadata="${realm}/.well-known/oauth-protected-resource"`,
/volume2/docker/payments-logger/backend/src/auth.js:40: `authorization_server="${HYDRA_PUBLIC_URL}"`,
/volume2/docker/payments-logger/backend/src/auth.js:52: * On success, attaches the decoded payload to req.tokenPayload.
/volume2/docker/payments-logger/backend/src/auth.js:54: * @param {Set<string>} publicPaths Paths to skip auth for.
/volume2/docker/payments-logger/backend/src/auth.js:58: '/.well-known/oauth-protected-resource',
/volume2/docker/payments-logger/backend/src/auth.js:59: '/.well-known/oauth-authorization-server',
/volume2/docker/payments-logger/backend/src/auth.js:66: const auth = req.headers.authorization || '';
/volume2/docker/payments-logger/backend/src/auth.js:67: if (!auth.toLowerCase().startsWith('bearer ')) {
/volume2/docker/payments-logger/backend/src/auth.js:68: return sendUnauthorized(res, 'Bearer token required', 'invalid_request');
/volume2/docker/payments-logger/backend/src/auth.js:71: const token = auth.slice(7).trim();
/volume2/docker/payments-logger/backend/src/auth.js:72: if (!token) {
/volume2/docker/payments-logger/backend/src/auth.js:73: return sendUnauthorized(res, 'Bearer token required', 'invalid_request');
/volume2/docker/payments-logger/backend/src/auth.js:82: const { payload } = await jwtVerify(token, getJwks(), verifyOptions);
/volume2/docker/payments-logger/backend/src/auth.js:83: req.tokenPayload = payload;
/volume2/docker/payments-logger/backend/src/auth.js:87: const error = msg.includes('expired') ? 'invalid_token' : 'invalid_token';
/volume2/docker/payments-logger/backend/src/auth.js:88: sendUnauthorized(res, msg, error);
/volume2/docker/payments-logger/backend/src/auth.js:98:wellKnownRouter.get('/.well-known/oauth-protected-resource', (_req, res) => {
/volume2/docker/payments-logger/backend/src/auth.js:103: authorization_servers: [HYDRA_PUBLIC_URL],
/volume2/docker/payments-logger/backend/src/auth.js:111:wellKnownRouter.get('/.well-known/oauth-authorization-server', async (_req, res) => {
/volume2/docker/payments-logger/backend/src/auth.js:119: authorization_endpoint: doc.authorization_endpoint,
/volume2/docker/payments-logger/backend/src/auth.js:120: token_endpoint: doc.token_endpoint,
/volume2/docker/payments-logger/backend/src/auth.js:123: grant_types_supported: doc.grant_types_supported || ['authorization_code', 'refresh_token'],
/volume2/docker/payments-logger/backend/src/auth.js:124: [API_KEY]: doc.[API_KEY] || ['none', 'client_secret_basic'],
/volume2/docker/payments-logger/backend/src/auth.js:128: id_token_signing_alg_values_supported: doc.id_token_signing_alg_values_supported || ['RS256'],
/volume2/docker/payments-logger/backend/src/routes/payments.js:58:// ── Ingest a payment (public — no auth) ──────────────────────────────────────
Bash
IN
find /volume2/docker/payments-logger/frontend/src -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | head -20
Copy code to clipboard
OUT
/volume2/docker/payments-logger/frontend/src/main.jsx
/volume2/docker/payments-logger/frontend/src/App.jsx
/volume2/docker/payments-logger/frontend/src/auth.js
/volume2/docker/payments-logger/frontend/src/components/PaymentCard.jsx
/volume2/docker/payments-logger/frontend/src/components/PaymentList.jsx
/volume2/docker/payments-logger/frontend/src/components/FilterBar.jsx
/volume2/docker/payments-logger/frontend/src/components/PaymentTable.jsx
/volume2/docker/payments-logger/frontend/src/components/AuthProvider.jsx
/volume2/docker/payments-logger/frontend/src/components/AuthCallback.jsx
Read
AuthProvider.jsx
AuthProvider.jsx
Read
AuthCallback.jsx
AuthCallback.jsx
Read
App.jsx
App.jsx
Read
main.jsx
main.jsx
Read
vite.config.js
vite.config.js
Bash
IN
grep -r "HYDRA\|VITE" /volume2/docker/payments-logger --include=".env*" -n
Copy code to clipboard
OUT
(Bash completed with no output)
Read
docker-compose.yml
docker-compose.yml
Bash
IN
grep -r "API_KEY" /volume2/docker/payments-logger/backend --include="*.js" -n
Copy code to clipboard
OUT
(Bash completed with no output)
Read
README.md
README.md
Bash
IN
grep -n "HYDRA\|oauth\|TOKEN" /volume2/docker/payments-logger/backend/src/index.js /volume2/docker/payments-logger/backend/src/auth.js | head -40
Copy code to clipboard
OUT
/volume2/docker/payments-logger/backend/src/auth.js:6: * - wellKnownRouter — serves /.well-known/oauth-* discovery endpoints
/volume2/docker/payments-logger/backend/src/auth.js:11:const HYDRA_PUBLIC_URL = (process.env.HYDRA_PUBLIC_URL || '').replace(/\/$/, '');
/volume2/docker/payments-logger/backend/src/auth.js:24: new URL(`${HYDRA_PUBLIC_URL}/.well-known/jwks.json`)
/volume2/docker/payments-logger/backend/src/auth.js:39: `resource_metadata="${realm}/.well-known/oauth-protected-resource"`,
/volume2/docker/payments-logger/backend/src/auth.js:40: `authorization_server="${HYDRA_PUBLIC_URL}"`,
/volume2/docker/payments-logger/backend/src/auth.js:58: '/.well-known/oauth-protected-resource',
/volume2/docker/payments-logger/backend/src/auth.js:59: '/.well-known/oauth-authorization-server',
/volume2/docker/payments-logger/backend/src/auth.js:78: issuer: HYDRA_PUBLIC_URL,
/volume2/docker/payments-logger/backend/src/auth.js:81: if (process.env.TOKEN_AUDIENCE) verifyOptions.audience = process.env.TOKEN_AUDIENCE;
/volume2/docker/payments-logger/backend/src/auth.js:98:wellKnownRouter.get('/.well-known/oauth-protected-resource', (_req, res) => {
/volume2/docker/payments-logger/backend/src/auth.js:103: authorization_servers: [HYDRA_PUBLIC_URL],
/volume2/docker/payments-logger/backend/src/auth.js:107: jwks_uri: `${HYDRA_PUBLIC_URL}/.well-known/jwks.json`,
/volume2/docker/payments-logger/backend/src/auth.js:111:wellKnownRouter.get('/.well-known/oauth-authorization-server', async (_req, res) => {
/volume2/docker/payments-logger/backend/src/auth.js:113: const r = await fetch(`${HYDRA_PUBLIC_URL}/.well-known/openid-configuration`);
/volume2/docker/payments-logger/backend/src/auth.js:118: issuer: doc.issuer || HYDRA_PUBLIC_URL,
Thinking
Thinking
payments-logger Authorization Overview
payments-logger Authorization Overview
The project uses
OAuth 2.1 with PKCE
via an external Hydra OAuth server at
hydra.lakylak.xyz
.
Auth Flow
Auth Flow
Frontend
(
frontend/src/auth.js
frontend/src/auth.js
):
Fetches OAuth server metadata via discovery endpoint
Generates a PKCE code verifier/challenge (SHA-256)
Redirects user to Hydra login with
code_challenge
On callback, exchanges code + verifier for tokens
Stores
access_token
,
refresh_token
in
localStorage
(
pl_oauth_tokens
)
Auto-refreshes token 30 seconds before expiry
Backend
(
backend/src/auth.js
backend/src/auth.js
):
bearerTokenMiddleware
validates the
Authorization: Bearer <token>
header
Fetches Hydra's JWKS (cached 300s) and verifies JWT signature (RS256/ES256/PS256)
Validates issuer (
[URL_WITH_CREDENTIALS]
const prisma = new PrismaClient();
const [ENV_SECRET];
const JWT_EXPIRE_MINS = parseInt(process.env.JWT_EXPIRE_MINUTES || '1440', 10);
if (!JWT_SECRET) {
console.error('FATAL: JWT_SECRET env var is required');
process.exit(1);
}
const secret = new TextEncoder().encode(JWT_SECRET);
// ── JWT helpers ───────────────────────────────────────────────────────────────
async function signToken(username) {
return new SignJWT({ sub: username })
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime(`${JWT_EXPIRE_MINS}m`)
.sign(secret);
}
async function verifyToken(token) {
const { payload } = await jwtVerify(token, secret, { algorithms: ['HS256'] });
return payload;
}
// ── Middleware ────────────────────────────────────────────────────────────────
function bearerTokenMiddleware(publicPaths) {
const _public = new Set(publicPaths);
return async (req, res, next) => {
if (_public.has(req.path)) return next();
const auth = req.headers.authorization || '';
if (!auth.toLowerCase().startsWith('bearer ')) {
return res.status(401).json({ error: 'Bearer token required' });
}
const token = auth.slice(7).trim();
try {
req.tokenPayload = await verifyToken(token);
next();
} catch (err) {
res.status(401).json({ error: 'Invalid or expired token' });
}
};
}
// ── Auth routes ───────────────────────────────────────────────────────────────
const authRouter = express.Router();
authRouter.post('/auth/register', async (req, res) => {
const { username, password } = req.body || {};
if (!username || !password) {
return res.status(400).json({ error: 'username and password are required' });
}
if (typeof username !== 'string' || username.length > 100) {
return res.status(400).json({ error: 'username must be a string under 100 chars' });
}
if (typeof password !== 'string' || password.length < 8) {
return res.status(400).json({ error: 'password must be at least 8 characters' });
}
try {
const existing = await prisma.user.findUnique({ where: { username } });
if (existing) {
return res.status(409).json({ error: 'Username already taken' });
}
const hashedPassword = [PASSWORD] bcrypt.hash(password, 10);
await prisma.user.create({ data: { username, hashedPassword } });
const token = await signToken(username);
res.status(201).json({ access_token: token, token_type: 'bearer', expires_in: JWT_EXPIRE_MINS * 60 });
} catch (err) {
console.error('Register error:', err);
res.status(500).json({ error: 'Registration failed' });
}
});
authRouter.post('/auth/login', async (req, res) => {
const { username, password } = req.body || {};
if (!username || !password) {
return res.status(400).json({ error: 'username and password are required' });
}
try {
const user = await prisma.user.findUnique({ where: { username } });
// Always run bcrypt compare to prevent timing-based username enumeration
const dummyHash = '$2a$10$abcdefghijklmnopqrstuuABCDEFGHIJKLMNOPQRSTUVWXYZ012345';
const valid = user
? await bcrypt.compare(password, user.hashedPassword)
: await bcrypt.compare(password, dummyHash).then(() => false);
if (!valid) {
return res.status(401).json({ error: 'Invalid username or password' });
}
const token = await signToken(username);
res.json({ access_token: token, token_type: 'bearer', expires_in: JWT_EXPIRE_MINS * 60 });
} catch (err) {
console.error('Login error:', err);
res.status(500).json({ error: 'Login failed' });
}
});
module.exports = { bearerTokenMiddleware, authRouter };
Update Todos
Add bcryptjs to backend package.json
Rewrite backend/src/auth.js (HS256 JWT + bcrypt, login/register routes)
Update backend/src/index.js (remove wellKnownRouter, mount authRouter)
Add User model to prisma/schema.prisma
Create Prisma migration for users table
Rewrite frontend/src/auth.js (simple username/password login)
Rewrite frontend/src/components/AuthProvider.jsx (login form instead of PKCE redirect)
Update frontend/src/main.jsx (remove /auth/callback handling)
Delete frontend/src/components/AuthCallback.jsx
Update frontend/vite.config.js (remove /.well-known proxy)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Explorer (⇧⌘E)","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":true},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Search (⇧⌘F)","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Source Control (⌃⇧G) - 55 pending changes","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"55","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Run and Debug (⇧⌘D)","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Remote Explorer","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Extensions (⇧⌘X) - 2 require update","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":22,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Claude Code","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Containers","depth":19,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"EXPLORER","depth":17,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"EXPLORER","depth":18,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Explorer Section: docker [SSH: nas]","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"Explorer Section: docker [SSH: nas]","depth":22,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"DOCKER [SSH: NAS]","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"adguard","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ai-stack","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app-db","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"appflowy","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"audiobookshelf","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"auth","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"beszel","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bitwarden","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"dawarich","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"dsk-uploader","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"finance","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"payments-logger","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"flask-app","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"garmin-connector","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"gitea","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"health","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"health-tracker","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"homarr","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"hst","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"immich","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jellyfinht","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"kavita","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"libreoffice","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"linkwarden","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"location-logger","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"alembic","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mcp-server","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.example","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".gitignore","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".mcp.json","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"alembic.ini","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"docker-compose.yml","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Dockerfile","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"README.md","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"requirements.txt","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"M","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"today_map.html","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mariadb","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"meeting-detector","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"mindfulmama","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"n8n","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"notifier-app","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"npm","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"oauth","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"obsidian","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ollama","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"open-webui","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"openttd","depth":27,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Outline Section","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"OUTLINE","depth":22,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"OUTLINE","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Timeline Section","depth":21,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"TIMELINE","depth":22,"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"TIMELINE","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"docker-compose.yml, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"docker-compose.yml, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"docker-compose.yml, Editor Group 1","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"services:\n\n postgresql:\n image: docker.io/library/postgres:16-alpine\n container_name: Authentik-DB\n hostname: authentik-db\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}\"]\n interval: 5s\n timeout: 5s\n retries: 5\n environment:\n POSTGRES_PASSWORD: ${PG_PASS}\n POSTGRES_USER: authentik\n POSTGRES_DB: authentik\n volumes:\n - /volume2/docker/auth/db:/var/lib/postgresql/data\n networks:\n - authentik_internal\n\n redis:\n image: docker.io/library/redis:alpine\n container_name: Authentik-REDIS\n hostname: authentik-redis\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"redis-cli ping | grep PONG\"]\n interval: 5s\n timeout: 3s\n retries: 5\n networks:\n - authentik_internal\n\n server:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Server\n hostname: authentik-server\n restart: unless-stopped\n command: server\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n AUTHENTIK_ERROR_REPORTING__ENABLED: \"false\"\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}\n AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD}\n ports:\n - \"9100:9000\"\n volumes:\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n - proxy\n\n worker:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Worker\n hostname: authentik-worker\n restart: unless-stopped\n command: worker\n user: root\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/certs:/certs\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n\n outpost:\n image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}\n container_name: Authentik-Outpost\n hostname: authentik-outpost\n restart: unless-stopped\n environment:\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_INSECURE: \"false\"\n AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}\n ports:\n - \"9101:9000\"\n depends_on:\n - server\n networks:\n - authentik_internal\n - proxy\n\nnetworks:\n authentik_internal:\n internal: true\n proxy:\n external: true","depth":28,"on_screen":true,"value":"services:\n\n postgresql:\n image: docker.io/library/postgres:16-alpine\n container_name: Authentik-DB\n hostname: authentik-db\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}\"]\n interval: 5s\n timeout: 5s\n retries: 5\n environment:\n POSTGRES_PASSWORD: ${PG_PASS}\n POSTGRES_USER: authentik\n POSTGRES_DB: authentik\n volumes:\n - /volume2/docker/auth/db:/var/lib/postgresql/data\n networks:\n - authentik_internal\n\n redis:\n image: docker.io/library/redis:alpine\n container_name: Authentik-REDIS\n hostname: authentik-redis\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"redis-cli ping | grep PONG\"]\n interval: 5s\n timeout: 3s\n retries: 5\n networks:\n - authentik_internal\n\n server:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Server\n hostname: authentik-server\n restart: unless-stopped\n command: server\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n AUTHENTIK_ERROR_REPORTING__ENABLED: \"false\"\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}\n AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD}\n ports:\n - \"9100:9000\"\n volumes:\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n - proxy\n\n worker:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Worker\n hostname: authentik-worker\n restart: unless-stopped\n command: worker\n user: root\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/certs:/certs\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n\n outpost:\n image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}\n container_name: Authentik-Outpost\n hostname: authentik-outpost\n restart: unless-stopped\n environment:\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_INSECURE: \"false\"\n AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}\n ports:\n - \"9101:9000\"\n depends_on:\n - server\n networks:\n - authentik_internal\n - proxy\n\nnetworks:\n authentik_internal:\n internal: true\n proxy:\n external: true","role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"services:\n\n postgresql:\n image: docker.io/library/postgres:16-alpine\n container_name: Authentik-DB\n hostname: authentik-db\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}\"]\n interval: 5s\n timeout: 5s\n retries: 5\n environment:\n POSTGRES_PASSWORD: ${PG_PASS}\n POSTGRES_USER: authentik\n POSTGRES_DB: authentik\n volumes:\n - /volume2/docker/auth/db:/var/lib/postgresql/data\n networks:\n - authentik_internal\n\n redis:\n image: docker.io/library/redis:alpine\n container_name: Authentik-REDIS\n hostname: authentik-redis\n restart: unless-stopped\n security_opt:\n - no-new-privileges:true\n healthcheck:\n test: [\"CMD-SHELL\", \"redis-cli ping | grep PONG\"]\n interval: 5s\n timeout: 3s\n retries: 5\n networks:\n - authentik_internal\n\n server:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Server\n hostname: authentik-server\n restart: unless-stopped\n command: server\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n AUTHENTIK_ERROR_REPORTING__ENABLED: \"false\"\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}\n AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD}\n ports:\n - \"9100:9000\"\n volumes:\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n - proxy\n\n worker:\n image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}\n container_name: Authentik-Worker\n hostname: authentik-worker\n restart: unless-stopped\n command: worker\n user: root\n environment:\n AUTHENTIK_REDIS__HOST: authentik-redis\n AUTHENTIK_POSTGRESQL__HOST: authentik-db\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}\n AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - /volume2/docker/auth/media:/media\n - /volume2/docker/auth/certs:/certs\n - /volume2/docker/auth/templates:/templates\n depends_on:\n postgresql:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - authentik_internal\n\n outpost:\n image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}\n container_name: Authentik-Outpost\n hostname: authentik-outpost\n restart: unless-stopped\n environment:\n AUTHENTIK_HOST: ${AUTHENTIK_HOST}\n AUTHENTIK_INSECURE: \"false\"\n AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}\n ports:\n - \"9101:9000\"\n depends_on:\n - server\n networks:\n - authentik_internal\n - proxy\n\nnetworks:\n authentik_internal:\n internal: true\n proxy:\n external: true","depth":29,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Review payment logger au…, Editor Group 2","depth":28,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"Problems (⇧⌘M)","depth":22,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PROBLEMS","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Output (⇧⌘U)","depth":22,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUTPUT","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Debug Console (⇧⌘Y)","depth":22,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DEBUG CONSOLE","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Terminal (⌃`)","depth":22,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":true},{"role":"AXStaticText","text":"TERMINAL","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Ports","depth":22,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PORTS","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"remote SSH: nas","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SSH: nas","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"location-logger (Git)","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"location-logger","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"location-logger (Git) - main*, Checkout Branch/Tag...","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"main*","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"location-logger (Git) - Synchronize Changes","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"No Problems","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"No Ports Forwarded","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Notifications","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sign In","depth":16,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Sign In","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"collapsed","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Command Succeeded","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Review payment logger authorization implementation","depth":19,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Session history","depth":19,"on_screen":true,"help_text":"Session history","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New session","depth":19,"on_screen":true,"help_text":"New session","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Message actions","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"review payment_logger project how toes authorization work","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Let me explore the payment_logger project structure first.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Find payment_logger project files","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker -type f -name \"*.py\" -o -name \"*.yml\" -o -name \"*.yaml\" -o -name \"*.env\" -o -name \"*.toml\" -o -name \"*.cfg\" | grep -i payment | head -50","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"bfs: error: /volume2/docker/portnotedb/pg_commit_ts: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_dynshmem: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_notify: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_serial: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_snapshots: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_subtrans: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_twophase: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_multixact: Permission denied.\nbfs: error: /volume2/docker/portnotedb/base: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_replslot: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_tblspc: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_stat: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_stat_tmp: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_xact: Permission denied.\nbfs: error: /volume2/docker/portnotedb/pg_logical: Permission denied.\nbfs: error: /volume2/docker/openttd/.dbus: Permission denied.\nbfs: error: /volume2/docker/immich/db: Permission denied.\nbfs: error: /volume2/docker/paperlessngx/db: Permission denied.\nbfs: error: /volume2/docker/appflowy/postgres: Permission denied.\nbfs: error: /volume2/docker/auth/db: Permission denied.\nbfs: error: /volume2/docker/openttd/.XDG/dbus-1: Permission denied.\nbfs: error: /volume2/docker/openttd/.config/pulse: Permission denied.\nbfs: error: /volume2/docker/openttd/.cache/openbox/sessions: Permission denied.\n/volume2/docker/payments-logger/.env\n/volume2/docker/payments-logger/docker-compose.yml\n/volume2/docker/payments-logger/backend/prisma/migrations/migration_lock.toml","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List docker directory contents","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ls /volume2/docker/","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"adguard\nai-stack\napp-db\nappflowy\naudiobookshelf\nauth\nbeszel\nbitwarden\ndawarich\ndsk-uploader\nflask-app\ngarmin-connector\ngitea\nhealth\nhealth-tracker\nhomarr\nhst\nimmich\njellyfinht\nkavita\nlibreoffice\nlinkwarden\nlocation-logger\nmariadb\nmeeting-detector\nmindfulmama\nn8n\nnotifier-app\nnpm\noauth\nobsidian\nollama\nopenttd\nopenvpn-client\nopen-webui\norchestrator\noutfit-app\nowntracks-stack\npaperlessngx\npayments-logger\npersonal-log\npersonal-log-system\nplayer\nportainer\nportnotedb\nreminders-app\nromm\nsecond-brain\nstatic\nstirling\nsyncthing\ntailscale\ntemp-logger\ntest-app\ntmp\ntorrent-stack\ntree\ntrilium\ntubearchivist\ntwenty\nuptimekuma\nytptube","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore payment_logger authorization code","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore the payments-logger project at /volume2/docker/payments-logger and give me a thorough understanding of how authorization works. I need to know:\n\n1. What auth mechanism is used (JWT, sessions, API keys, OAuth, etc.)\n2. Where auth is enforced (middleware, decorators, route guards, etc.)\n3. What roles/permissions exist\n4. How tokens are issued, validated, and refreshed\n5. Any auth-related config (env vars, settings)\n\nPlease read the key source files and give me a clear summary with file paths and line numbers for the important parts.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker/payments-logger -type f -name \"*.py\" -o -name \"*.json\" -o -name \"*.yml\" -o -name \"*.yaml\" | grep -E \"(auth|token|jwt|session|permission|role)\" | head -20","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ls -la /volume2/docker/payments-logger/ 2>/dev/null || echo \"Directory not found\"","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"total 36\ndrwxrwxrwx 1 Adm1n admin 162 Mar 29 18:01 .\ndrwxrwxrwx 1 root root 1146 Apr 26 18:49 ..\n-rwxrwxrwx 1 Adm1n admin 15233 Feb 22 17:08 API.md\ndrwxrwxrwx 1 Adm1n admin 88 Mar 29 15:41 backend\ndrwxrwxrwx 1 Adm1n admin 38 Mar 29 17:07 .claude\n-rwxrwxrwx 1 Adm1n admin 1502 Mar 29 18:01 docker-compose.yml\n-rwxrwxrwx 1 Adm1n admin 1066 Mar 29 15:44 .env\n-rwxrwxrwx 1 Adm1n admin 1078 Feb 14 17:53 .env.example\ndrwxrwxrwx 1 Adm1n admin 194 Mar 29 15:44 frontend\n-rwxrwxrwx 1 Adm1n admin 19 Feb 14 17:54 .gitignore\n-rwxrwxrwx 1 Adm1n admin 4052 Feb 14 19:06 README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker/payments-logger/backend -type f | head -30","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/payments-logger/backend/Dockerfile\n/volume2/docker/payments-logger/backend/.dockerignore\n/volume2/docker/payments-logger/backend/package.json\n/volume2/docker/payments-logger/backend/prisma/schema.prisma\n/volume2/docker/payments-logger/backend/src/parser.js\n/volume2/docker/payments-logger/backend/src/index.js\n/volume2/docker/payments-logger/backend/src/auth.js\n/volume2/docker/payments-logger/backend/prisma/migrations/migration_lock.toml\n/volume2/docker/payments-logger/backend/src/routes/payments.js\n/volume2/docker/payments-logger/backend/prisma/migrations/20260210_init/migration.sql\n/volume2/docker/payments-logger/backend/prisma/migrations/20260210_simplify/migration.sql\n/volume2/docker/payments-logger/backend/prisma/migrations/20260222_add_card/migration.sql","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker/payments-logger -type f \\( -name \"*.js\" -o -name \"*.json\" -o -name \"*.md\" \\) | sort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/payments-logger/API.md\n/volume2/docker/payments-logger/backend/package.json\n/volume2/docker/payments-logger/backend/src/auth.js\n/volume2/docker/payments-logger/backend/src/index.js\n/volume2/docker/payments-logger/backend/src/parser.js\n/volume2/docker/payments-logger/backend/src/routes/payments.js\n/volume2/docker/payments-logger/.claude/settings.local.json\n/volume2/docker/payments-logger/frontend/package.json\n/volume2/docker/payments-logger/frontend/postcss.config.js\n/volume2/docker/payments-logger/frontend/src/auth.js\n/volume2/docker/payments-logger/frontend/tailwind.config.js\n/volume2/docker/payments-logger/frontend/vite.config.js\n/volume2/docker/payments-logger/README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"auth.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"auth.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"index.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"index.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"package.json","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"package.json","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"auth.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"auth.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"API.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"API.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"payments.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"payments.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env.example","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env.example","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"schema.prisma","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"schema.prisma","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -r \"API_KEY\\|auth\\|token\\|oauth\\|hydra\" /volume2/docker/payments-logger/backend/src --include=\"*.js\" -n","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/payments-logger/backend/src/index.js:6:const { bearerTokenMiddleware, wellKnownRouter } = require('./auth');\n/volume2/docker/payments-logger/backend/src/index.js:18:// ── OAuth Bearer token auth (skips public paths) ──────────────────────────────\n/volume2/docker/payments-logger/backend/src/auth.js:2: * OAuth 2.1 / Hydra JWT authentication for Express.\n/volume2/docker/payments-logger/backend/src/auth.js:6: * - wellKnownRouter — serves /.well-known/oauth-* discovery endpoints\n/volume2/docker/payments-logger/backend/src/auth.js:33:function sendUnauthorized(res, detail, error = 'invalid_token') {\n/volume2/docker/payments-logger/backend/src/auth.js:39: `resource_metadata=\"${realm}/.well-known/oauth-protected-resource\"`,\n/volume2/docker/payments-logger/backend/src/auth.js:40: `authorization_server=\"${HYDRA_PUBLIC_URL}\"`,\n/volume2/docker/payments-logger/backend/src/auth.js:52: * On success, attaches the decoded payload to req.tokenPayload.\n/volume2/docker/payments-logger/backend/src/auth.js:54: * @param {Set<string>} publicPaths Paths to skip auth for.\n/volume2/docker/payments-logger/backend/src/auth.js:58: '/.well-known/oauth-protected-resource',\n/volume2/docker/payments-logger/backend/src/auth.js:59: '/.well-known/oauth-authorization-server',\n/volume2/docker/payments-logger/backend/src/auth.js:66: const auth = req.headers.authorization || '';\n/volume2/docker/payments-logger/backend/src/auth.js:67: if (!auth.toLowerCase().startsWith('bearer ')) {\n/volume2/docker/payments-logger/backend/src/auth.js:68: return sendUnauthorized(res, 'Bearer token required', 'invalid_request');\n/volume2/docker/payments-logger/backend/src/auth.js:71: const token = auth.slice(7).trim();\n/volume2/docker/payments-logger/backend/src/auth.js:72: if (!token) {\n/volume2/docker/payments-logger/backend/src/auth.js:73: return sendUnauthorized(res, 'Bearer token required', 'invalid_request');\n/volume2/docker/payments-logger/backend/src/auth.js:82: const { payload } = await jwtVerify(token, getJwks(), verifyOptions);\n/volume2/docker/payments-logger/backend/src/auth.js:83: req.tokenPayload = payload;\n/volume2/docker/payments-logger/backend/src/auth.js:87: const error = msg.includes('expired') ? 'invalid_token' : 'invalid_token';\n/volume2/docker/payments-logger/backend/src/auth.js:88: sendUnauthorized(res, msg, error);\n/volume2/docker/payments-logger/backend/src/auth.js:98:wellKnownRouter.get('/.well-known/oauth-protected-resource', (_req, res) => {\n/volume2/docker/payments-logger/backend/src/auth.js:103: authorization_servers: [HYDRA_PUBLIC_URL],\n/volume2/docker/payments-logger/backend/src/auth.js:111:wellKnownRouter.get('/.well-known/oauth-authorization-server', async (_req, res) => {\n/volume2/docker/payments-logger/backend/src/auth.js:119: authorization_endpoint: doc.authorization_endpoint,\n/volume2/docker/payments-logger/backend/src/auth.js:120: token_endpoint: doc.token_endpoint,\n/volume2/docker/payments-logger/backend/src/auth.js:123: grant_types_supported: doc.grant_types_supported || ['authorization_code', 'refresh_token'],\n/volume2/docker/payments-logger/backend/src/auth.js:124: token_endpoint_auth_methods_supported: doc.token_endpoint_auth_methods_supported || ['none', 'client_secret_basic'],\n/volume2/docker/payments-logger/backend/src/auth.js:128: id_token_signing_alg_values_supported: doc.id_token_signing_alg_values_supported || ['RS256'],\n/volume2/docker/payments-logger/backend/src/routes/payments.js:58:// ── Ingest a payment (public — no auth) ──────────────────────────────────────","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker/payments-logger/frontend/src -type f -name \"*.js\" -o -name \"*.jsx\" -o -name \"*.ts\" -o -name \"*.tsx\" | head -20","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/payments-logger/frontend/src/main.jsx\n/volume2/docker/payments-logger/frontend/src/App.jsx\n/volume2/docker/payments-logger/frontend/src/auth.js\n/volume2/docker/payments-logger/frontend/src/components/PaymentCard.jsx\n/volume2/docker/payments-logger/frontend/src/components/PaymentList.jsx\n/volume2/docker/payments-logger/frontend/src/components/FilterBar.jsx\n/volume2/docker/payments-logger/frontend/src/components/PaymentTable.jsx\n/volume2/docker/payments-logger/frontend/src/components/AuthProvider.jsx\n/volume2/docker/payments-logger/frontend/src/components/AuthCallback.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"AuthProvider.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"AuthProvider.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"AuthCallback.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"AuthCallback.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"App.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"App.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"main.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"main.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"vite.config.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"vite.config.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -r \"HYDRA\\|VITE\" /volume2/docker/payments-logger --include=\".env*\" -n","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"docker-compose.yml","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -r \"API_KEY\" /volume2/docker/payments-logger/backend --include=\"*.js\" -n","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(Bash completed with no output)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"README.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"grep -n \"HYDRA\\|oauth\\|TOKEN\" /volume2/docker/payments-logger/backend/src/index.js /volume2/docker/payments-logger/backend/src/auth.js | head -40","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/payments-logger/backend/src/auth.js:6: * - wellKnownRouter — serves /.well-known/oauth-* discovery endpoints\n/volume2/docker/payments-logger/backend/src/auth.js:11:const HYDRA_PUBLIC_URL = (process.env.HYDRA_PUBLIC_URL || '').replace(/\\/$/, '');\n/volume2/docker/payments-logger/backend/src/auth.js:24: new URL(`${HYDRA_PUBLIC_URL}/.well-known/jwks.json`)\n/volume2/docker/payments-logger/backend/src/auth.js:39: `resource_metadata=\"${realm}/.well-known/oauth-protected-resource\"`,\n/volume2/docker/payments-logger/backend/src/auth.js:40: `authorization_server=\"${HYDRA_PUBLIC_URL}\"`,\n/volume2/docker/payments-logger/backend/src/auth.js:58: '/.well-known/oauth-protected-resource',\n/volume2/docker/payments-logger/backend/src/auth.js:59: '/.well-known/oauth-authorization-server',\n/volume2/docker/payments-logger/backend/src/auth.js:78: issuer: HYDRA_PUBLIC_URL,\n/volume2/docker/payments-logger/backend/src/auth.js:81: if (process.env.TOKEN_AUDIENCE) verifyOptions.audience = process.env.TOKEN_AUDIENCE;\n/volume2/docker/payments-logger/backend/src/auth.js:98:wellKnownRouter.get('/.well-known/oauth-protected-resource', (_req, res) => {\n/volume2/docker/payments-logger/backend/src/auth.js:103: authorization_servers: [HYDRA_PUBLIC_URL],\n/volume2/docker/payments-logger/backend/src/auth.js:107: jwks_uri: `${HYDRA_PUBLIC_URL}/.well-known/jwks.json`,\n/volume2/docker/payments-logger/backend/src/auth.js:111:wellKnownRouter.get('/.well-known/oauth-authorization-server', async (_req, res) => {\n/volume2/docker/payments-logger/backend/src/auth.js:113: const r = await fetch(`${HYDRA_PUBLIC_URL}/.well-known/openid-configuration`);\n/volume2/docker/payments-logger/backend/src/auth.js:118: issuer: doc.issuer || HYDRA_PUBLIC_URL,","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"payments-logger Authorization Overview","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"payments-logger Authorization Overview","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The project uses","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"OAuth 2.1 with PKCE","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"via an external Hydra OAuth server at","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"hydra.lakylak.xyz","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Auth Flow","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Auth Flow","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Frontend","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"frontend/src/auth.js","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"frontend/src/auth.js","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"):","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fetches OAuth server metadata via discovery endpoint","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Generates a PKCE code verifier/challenge (SHA-256)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redirects user to Hydra login with","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"code_challenge","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"On callback, exchanges code + verifier for tokens","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Stores","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"access_token","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"refresh_token","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"in","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"localStorage","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"pl_oauth_tokens","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":")","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Auto-refreshes token 30 seconds before expiry","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Backend","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"backend/src/auth.js","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"backend/src/auth.js","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"):","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"bearerTokenMiddleware","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"validates the","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Authorization: Bearer <token>","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"header","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Fetches Hydra's JWKS (cached 300s) and verifies JWT signature (RS256/ES256/PS256)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Validates issuer (","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"https://hydra.lakylak.xyz","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":") and optional audience","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Enforcement","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Enforcement","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Applied globally in","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"backend/src/index.js:19","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"backend/src/index.js:19","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"with these","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"public (unprotected) paths","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":":","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/.well-known/oauth-protected-resource","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/.well-known/oauth-authorization-server","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/health","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/api/payments/ingest","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(rate-limited at 200 req/min — for SMS ingestion)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Roles/Permissions","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Roles/Permissions","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"No RBAC","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— it's binary: authenticated vs. unauthenticated. Required scopes:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"openid","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"offline_access","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXHeading","text":"Key Security Notes","depth":22,"on_screen":false,"role_description":"heading"},{"role":"AXStaticText","text":"Key Security Notes","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PKCE","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"prevents authorization code interception","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"State parameter","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"provides CSRF protection","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"No server-side token storage","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— validation is stateless via JWKS","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"The README/API docs mention an","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"X-API-Key","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"header, but that's","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"outdated","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"— the actual code uses Bearer tokens only","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Config lives in","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"docker-compose.yml","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(lines 30–33):","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HYDRA_PUBLIC_URL","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"REQUIRED_SCOPES","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"OAUTH_CLIENT_ID","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", and optionally","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TOKEN_AUDIENCE","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"JWKS_CACHE_TTL","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Message actions","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"compare it to location logger and make it the same. Lets remove hydra and only use authentic (or whatever location logger uses).","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Let me first explore how location-logger handles authorization.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Agent:","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore location-logger authorization code","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Explore the location-logger project at /volume2/docker/location-logger and give me a thorough understanding of how authorization works. I need to know:\n\n1. What auth mechanism is used (JWT, sessions, API keys, OAuth, etc.)\n2. Where auth is enforced (middleware, decorators, route guards, etc.)\n3. What roles/permissions exist\n4. How tokens are issued, validated, and refreshed\n5. Any auth-related config (env vars, settings)\n6. Frontend auth flow (how the user logs in, how tokens are stored and used)\n7. The full directory/file structure of the project\n\nPlease read ALL relevant source files completely and give me a detailed summary with file paths and line numbers. I need enough detail to replicate this auth system in another project.","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker/location-logger -type f -name \"*.py\" -o -name \"*.js\" -o -name \"*.ts\" -o -name \"*.json\" | head -50","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/location-logger/.mcp.json\n/volume2/docker/location-logger/app/__init__.py\n/volume2/docker/location-logger/app/utils.py\n/volume2/docker/location-logger/app/config.py\n/volume2/docker/location-logger/app/main.py\n/volume2/docker/location-logger/alembic/env.py\n/volume2/docker/location-logger/mcp-server/server.py\n/volume2/docker/location-logger/alembic/versions/20260203_201500_create_location_points_table.py\n/volume2/docker/location-logger/alembic/versions/20260209_200000_add_enhanced_fields_and_tables.py\n/volume2/docker/location-logger/alembic/versions/20260214_000000_add_users_and_audit_logs.py\n/volume2/docker/location-logger/alembic/versions/20260320_000000_add_audit_query_string.py\n/volume2/docker/location-logger/app/services/geofence_service.py\n/volume2/docker/location-logger/app/services/recorder_service.py\n/volume2/docker/location-logger/app/services/trip_service.py\n/volume2/docker/location-logger/app/services/enhanced_location_service.py\n/volume2/docker/location-logger/app/services/geocoding_service.py\n/volume2/docker/location-logger/app/clients/__init__.py\n/volume2/docker/location-logger/app/clients/dawarich_client.py\n/volume2/docker/location-logger/app/clients/owntracks_client.py\n/volume2/docker/location-logger/app/models/areas.py\n/volume2/docker/location-logger/app/models/geofence_events.py\n/volume2/docker/location-logger/app/models/trips.py\n/volume2/docker/location-logger/app/models/user.py\n/volume2/docker/location-logger/app/models/location.py\n/volume2/docker/location-logger/app/models/audit_log.py\n/volume2/docker/location-logger/app/auth/__init__.py\n/volume2/docker/location-logger/app/auth/dependencies.py\n/volume2/docker/location-logger/app/auth/utils.py\n/volume2/docker/location-logger/app/api/enhanced_endpoints.py\n/volume2/docker/location-logger/app/db/base.py\n/volume2/docker/location-logger/app/db/session.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"tree -L 4 /volume2/docker/location-logger 2>/dev/null || find /volume2/docker/location-logger -type d | sort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/location-logger\n├── alembic\n│ ├── env.py\n│ ├── script.py.mako\n│ └── versions\n│ ├── 20260203_201500_create_location_points_table.py\n│ ├── 20260209_200000_add_enhanced_fields_and_tables.py\n│ ├── 20260214_000000_add_users_and_audit_logs.py\n│ ├── 20260320_000000_add_audit_query_string.py\n│ └── __pycache__\n│ └── 20260214_000000_add_users_and_audit_logs.cpython-311.pyc\n├── alembic.ini\n├── app\n│ ├── api\n│ │ └── enhanced_endpoints.py\n│ ├── auth\n│ │ ├── dependencies.py\n│ │ ├── __init__.py\n│ │ ├── __pycache__\n│ │ │ ├── dependencies.cpython-311.pyc\n│ │ │ ├── __init__.cpython-311.pyc\n│ │ │ └── utils.cpython-311.pyc\n│ │ └── utils.py\n│ ├── clients\n│ │ ├── dawarich_client.py\n│ │ ├── __init__.py\n│ │ └── owntracks_client.py\n│ ├── config.py\n│ ├── db\n│ │ ├── base.py\n│ │ └── session.py\n│ ├── __init__.py\n│ ├── main.py\n│ ├── models\n│ │ ├── areas.py\n│ │ ├── audit_log.py\n│ │ ├── geofence_events.py\n│ │ ├── location.py\n│ │ ├── __pycache__\n│ │ │ ├── audit_log.cpython-311.pyc\n│ │ │ └── user.cpython-311.pyc\n│ │ ├── trips.py\n│ │ └── user.py\n│ ├── __pycache__\n│ │ ├── __init__.cpython-311.pyc\n│ │ └── main.cpython-311.pyc\n│ ├── services\n│ │ ├── enhanced_location_service.py\n│ │ ├── geocoding_service.py\n│ │ ├── geofence_service.py\n│ │ ├── recorder_service.py\n│ │ └── trip_service.py\n│ ├── static\n│ │ └── dashboard.html\n│ └── utils.py\n├── docker-compose.yml\n├── Dockerfile\n├── mcp-server\n│ ├── Dockerfile\n│ ├── requirements.txt\n│ └── server.py\n├── README.md\n├── requirements.txt\n└── today_map.html\n\n16 directories, 48 files","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"utils.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"utils.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"dependencies.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"dependencies.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"user.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"user.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"config.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"config.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"main.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"main.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"session.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"session.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"dashboard.html","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"dashboard.html","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"audit_log.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"audit_log.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"20260214_000000_add_users_and_audit_logs.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"20260214_000000_add_users_and_audit_logs.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"20260320_000000_add_audit_query_string.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"20260320_000000_add_audit_query_string.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"README.md","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"requirements.txt","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"requirements.txt","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"server.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"server.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"server.py","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"server.py","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(lines 101-400)","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now I have a full picture of both systems. Let me read the payments-logger source files before planning the migration.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Bash","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List all payments-logger files","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IN","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"find /volume2/docker/payments-logger -type f | grep -v node_modules | grep -v .git | sort","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Copy code to clipboard","depth":24,"on_screen":false,"help_text":"Copy code","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUT","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/volume2/docker/payments-logger/API.md\n/volume2/docker/payments-logger/backend/Dockerfile\n/volume2/docker/payments-logger/backend/.dockerignore\n/volume2/docker/payments-logger/backend/package.json\n/volume2/docker/payments-logger/backend/prisma/migrations/20260210_init/migration.sql\n/volume2/docker/payments-logger/backend/prisma/migrations/20260210_simplify/migration.sql\n/volume2/docker/payments-logger/backend/prisma/migrations/20260222_add_card/migration.sql\n/volume2/docker/payments-logger/backend/prisma/migrations/migration_lock.toml\n/volume2/docker/payments-logger/backend/prisma/schema.prisma\n/volume2/docker/payments-logger/backend/src/auth.js\n/volume2/docker/payments-logger/backend/src/index.js\n/volume2/docker/payments-logger/backend/src/parser.js\n/volume2/docker/payments-logger/backend/src/routes/payments.js\n/volume2/docker/payments-logger/.claude/settings.local.json\n/volume2/docker/payments-logger/docker-compose.yml\n/volume2/docker/payments-logger/.env\n/volume2/docker/payments-logger/.env.example\n/volume2/docker/payments-logger/frontend/Dockerfile\n/volume2/docker/payments-logger/frontend/.dockerignore\n/volume2/docker/payments-logger/frontend/index.html\n/volume2/docker/payments-logger/frontend/package.json\n/volume2/docker/payments-logger/frontend/postcss.config.js\n/volume2/docker/payments-logger/frontend/src/App.jsx\n/volume2/docker/payments-logger/frontend/src/auth.js\n/volume2/docker/payments-logger/frontend/src/components/AuthCallback.jsx\n/volume2/docker/payments-logger/frontend/src/components/AuthProvider.jsx\n/volume2/docker/payments-logger/frontend/src/components/FilterBar.jsx\n/volume2/docker/payments-logger/frontend/src/components/PaymentCard.jsx\n/volume2/docker/payments-logger/frontend/src/components/PaymentList.jsx\n/volume2/docker/payments-logger/frontend/src/components/PaymentTable.jsx\n/volume2/docker/payments-logger/frontend/src/index.css\n/volume2/docker/payments-logger/frontend/src/main.jsx\n/volume2/docker/payments-logger/frontend/tailwind.config.js\n/volume2/docker/payments-logger/frontend/vite.config.js\n/volume2/docker/payments-logger/README.md","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"auth.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"auth.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"index.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"index.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"auth.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"auth.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"AuthProvider.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"AuthProvider.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"package.json","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"package.json","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"AuthCallback.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"AuthCallback.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"schema.prisma","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"schema.prisma","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"docker-compose.yml","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"docker-compose.yml","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now let me read the remaining frontend files.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"App.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"App.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"package.json","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"package.json","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Let me read the remaining files before making changes.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"main.jsx","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"main.jsx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"vite.config.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"vite.config.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"payments.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"payments.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Read","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":".env.example","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":".env.example","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Thinking","depth":23,"on_screen":false,"role_description":"disclosure triangle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Thinking","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Now I have everything I need. Here's what changes:","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Backend:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"auth.js","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"(HS256 JWT + bcrypt), add","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/auth/login","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"+","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/auth/register","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"endpoints, add","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"User","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"model to Prisma, new migration, remove Hydra env vars.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Frontend:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Replace PKCE flow with a simple login form in","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AuthProvider","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", simplify","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"auth.js","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", remove","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AuthCallback","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":", drop","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/.well-known","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"proxy.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Config:","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drop all Hydra/OAuth env vars, add","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"JWT_SECRET","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Let me implement everything now.","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Add bcryptjs to backend package.json","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite backend/src/auth.js (HS256 JWT + bcrypt, login/register routes)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update backend/src/index.js (remove wellKnownRouter, mount authRouter)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Add User model to prisma/schema.prisma","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create Prisma migration for users table","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite frontend/src/auth.js (simple username/password login)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite frontend/src/components/AuthProvider.jsx (login form instead of PKCE redirect)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update frontend/src/main.jsx (remove /auth/callback handling)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Delete frontend/src/components/AuthCallback.jsx","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update frontend/vite.config.js (remove /.well-known proxy)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update docker-compose.yml (remove Hydra vars/network, add JWT_SECRET)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Add bcryptjs to backend package.json","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite backend/src/auth.js (HS256 JWT + bcrypt, login/register routes)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update backend/src/index.js (remove wellKnownRouter, mount authRouter)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Add User model to prisma/schema.prisma","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create Prisma migration for users table","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite frontend/src/auth.js (simple username/password login)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite frontend/src/components/AuthProvider.jsx (login form instead of PKCE redirect)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update frontend/src/main.jsx (remove /auth/callback handling)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Delete frontend/src/components/AuthCallback.jsx","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update frontend/vite.config.js (remove /.well-known proxy)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update docker-compose.yml (remove Hydra vars/network, add JWT_SECRET)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Edit","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"package.json","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"package.json","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Added 1 line","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Add bcryptjs to backend package.json","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite backend/src/auth.js (HS256 JWT + bcrypt, login/register routes)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update backend/src/index.js (remove wellKnownRouter, mount authRouter)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Add User model to prisma/schema.prisma","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create Prisma migration for users table","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite frontend/src/auth.js (simple username/password login)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite frontend/src/components/AuthProvider.jsx (login form instead of PKCE redirect)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update frontend/src/main.jsx (remove /auth/callback handling)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Delete frontend/src/components/AuthCallback.jsx","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update frontend/vite.config.js (remove /.well-known proxy)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update docker-compose.yml (remove Hydra vars/network, add JWT_SECRET)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update .env and .env.example","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Write","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"auth.js","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"auth.js","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"116 lines","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"const express = require('express');\nconst bcrypt = require('bcryptjs');\nconst { SignJWT, jwtVerify } = require('jose');\nconst { PrismaClient } = require('@prisma/client');\n\nconst prisma = new PrismaClient();\n\nconst JWT_SECRET = process.env.JWT_SECRET;\nconst JWT_EXPIRE_MINS = parseInt(process.env.JWT_EXPIRE_MINUTES || '1440', 10);\n\nif (!JWT_SECRET) {\n console.error('FATAL: JWT_SECRET env var is required');\n process.exit(1);\n}\n\nconst secret = new TextEncoder().encode(JWT_SECRET);\n\n// ── JWT helpers ───────────────────────────────────────────────────────────────\n\nasync function signToken(username) {\n return new SignJWT({ sub: username })\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n .setExpirationTime(`${JWT_EXPIRE_MINS}m`)\n .sign(secret);\n}\n\nasync function verifyToken(token) {\n const { payload } = await jwtVerify(token, secret, { algorithms: ['HS256'] });\n return payload;\n}\n\n// ── Middleware ────────────────────────────────────────────────────────────────\n\nfunction bearerTokenMiddleware(publicPaths) {\n const _public = new Set(publicPaths);\n\n return async (req, res, next) => {\n if (_public.has(req.path)) return next();\n\n const auth = req.headers.authorization || '';\n if (!auth.toLowerCase().startsWith('bearer ')) {\n return res.status(401).json({ error: 'Bearer token required' });\n }\n\n const token = auth.slice(7).trim();\n try {\n req.tokenPayload = await verifyToken(token);\n next();\n } catch (err) {\n res.status(401).json({ error: 'Invalid or expired token' });\n }\n };\n}\n\n// ── Auth routes ───────────────────────────────────────────────────────────────\n\nconst authRouter = express.Router();\n\nauthRouter.post('/auth/register', async (req, res) => {\n const { username, password } = req.body || {};\n if (!username || !password) {\n return res.status(400).json({ error: 'username and password are required' });\n }\n if (typeof username !== 'string' || username.length > 100) {\n return res.status(400).json({ error: 'username must be a string under 100 chars' });\n }\n if (typeof password !== 'string' || password.length < 8) {\n return res.status(400).json({ error: 'password must be at least 8 characters' });\n }\n\n try {\n const existing = await prisma.user.findUnique({ where: { username } });\n if (existing) {\n return res.status(409).json({ error: 'Username already taken' });\n }\n\n const hashedPassword = await bcrypt.hash(password, 10);\n await prisma.user.create({ data: { username, hashedPassword } });\n\n const token = await signToken(username);\n res.status(201).json({ access_token: token, token_type: 'bearer', expires_in: JWT_EXPIRE_MINS * 60 });\n } catch (err) {\n console.error('Register error:', err);\n res.status(500).json({ error: 'Registration failed' });\n }\n});\n\nauthRouter.post('/auth/login', async (req, res) => {\n const { username, password } = req.body || {};\n if (!username || !password) {\n return res.status(400).json({ error: 'username and password are required' });\n }\n\n try {\n const user = await prisma.user.findUnique({ where: { username } });\n // Always run bcrypt compare to prevent timing-based username enumeration\n const dummyHash = '$2a$10$abcdefghijklmnopqrstuuABCDEFGHIJKLMNOPQRSTUVWXYZ012345';\n const valid = user\n ? await bcrypt.compare(password, user.hashedPassword)\n : await bcrypt.compare(password, dummyHash).then(() => false);\n\n if (!valid) {\n return res.status(401).json({ error: 'Invalid username or password' });\n }\n\n const token = await signToken(username);\n res.json({ access_token: token, token_type: 'bearer', expires_in: JWT_EXPIRE_MINS * 60 });\n } catch (err) {\n console.error('Login error:', err);\n res.status(500).json({ error: 'Login failed' });\n }\n});\n\nmodule.exports = { bearerTokenMiddleware, authRouter };","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update Todos","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Add bcryptjs to backend package.json","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite backend/src/auth.js (HS256 JWT + bcrypt, login/register routes)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update backend/src/index.js (remove wellKnownRouter, mount authRouter)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Add User model to prisma/schema.prisma","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Create Prisma migration for users table","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite frontend/src/auth.js (simple username/password login)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Rewrite frontend/src/components/AuthProvider.jsx (login form instead of PKCE redirect)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update frontend/src/main.jsx (remove /auth/callback handling)","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Delete frontend/src/components/AuthCallback.jsx","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Update frontend/vite.config.js (remove /.well-known proxy)","depth":26,"on_screen":false,"role_description":"text"}]...
|
-9077139017369824126
|
3802054028445733452
|
click
|
accessibility
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G) - 55 pending changes
55
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: docker [SSH: nas]
Explorer Section: docker [SSH: nas]
DOCKER [SSH: NAS]
adguard
ai-stack
app-db
appflowy
audiobookshelf
auth
beszel
bitwarden
dawarich
dsk-uploader
finance
payments-logger
flask-app
garmin-connector
gitea
health
health-tracker
homarr
hst
immich
jellyfinht
kavita
libreoffice
linkwarden
location-logger
alembic
app
mcp-server
.env
.env.example
.gitignore
.mcp.json
M
alembic.ini
docker-compose.yml
M
Dockerfile
README.md
M
requirements.txt
M
today_map.html
mariadb
meeting-detector
mindfulmama
n8n
notifier-app
npm
oauth
obsidian
ollama
open-webui
openttd
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
docker-compose.yml, Editor Group 1
docker-compose.yml, Editor Group 1
docker-compose.yml, Editor Group 1
services:
postgresql:
image: docker.io/library/postgres:16-alpine
container_name: Authentik-DB
hostname: authentik-db
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}"]
interval: 5s
timeout: 5s
retries: 5
environment:
POSTGRES_PASSWORD: [PASSWORD]
POSTGRES_USER: authentik
POSTGRES_DB: authentik
volumes:
- /volume2/docker/auth/db:/var/lib/postgresql/data
networks:
- authentik_internal
redis:
image: docker.io/library/redis:alpine
container_name: Authentik-REDIS
hostname: authentik-redis
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 5s
timeout: 3s
retries: 5
networks:
- authentik_internal
server:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}
container_name: Authentik-Server
hostname: authentik-server
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: [PASSWORD]
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
AUTHENTIK_HOST: ${AUTHENTIK_HOST}
AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}
AUTHENTIK_BOOTSTRAP_PASSWORD: [PASSWORD]
ports:
- "9100:9000"
volumes:
- /volume2/docker/auth/media:/media
- /volume2/docker/auth/templates:/templates
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- authentik_internal
- proxy
worker:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}
container_name: Authentik-Worker
hostname: authentik-worker
restart: unless-stopped
command: worker
user: root
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: [PASSWORD]
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /volume2/docker/auth/media:/media
- /volume2/docker/auth/certs:/certs
- /volume2/docker/auth/templates:/templates
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- authentik_internal
outpost:
image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}
container_name: Authentik-Outpost
hostname: authentik-outpost
restart: unless-stopped
environment:
AUTHENTIK_HOST: ${AUTHENTIK_HOST}
AUTHENTIK_INSECURE: "false"
AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}
ports:
- "9101:9000"
depends_on:
- server
networks:
- authentik_internal
- proxy
networks:
authentik_internal:
internal: true
proxy:
external: true
services:
postgresql:
image: docker.io/library/postgres:16-alpine
container_name: Authentik-DB
hostname: authentik-db
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "pg_isready -d ${POSTGRES_DB:-authentik} -U ${POSTGRES_USER:-authentik}"]
interval: 5s
timeout: 5s
retries: 5
environment:
POSTGRES_PASSWORD: [PASSWORD]
POSTGRES_USER: authentik
POSTGRES_DB: authentik
volumes:
- /volume2/docker/auth/db:/var/lib/postgresql/data
networks:
- authentik_internal
redis:
image: docker.io/library/redis:alpine
container_name: Authentik-REDIS
hostname: authentik-redis
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 5s
timeout: 3s
retries: 5
networks:
- authentik_internal
server:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}
container_name: Authentik-Server
hostname: authentik-server
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: [PASSWORD]
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
AUTHENTIK_HOST: ${AUTHENTIK_HOST}
AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL}
AUTHENTIK_BOOTSTRAP_PASSWORD: [PASSWORD]
ports:
- "9100:9000"
volumes:
- /volume2/docker/auth/media:/media
- /volume2/docker/auth/templates:/templates
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- authentik_internal
- proxy
worker:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG}
container_name: Authentik-Worker
hostname: authentik-worker
restart: unless-stopped
command: worker
user: root
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: [PASSWORD]
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /volume2/docker/auth/media:/media
- /volume2/docker/auth/certs:/certs
- /volume2/docker/auth/templates:/templates
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- authentik_internal
outpost:
image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG}
container_name: Authentik-Outpost
hostname: authentik-outpost
restart: unless-stopped
environment:
AUTHENTIK_HOST: ${AUTHENTIK_HOST}
AUTHENTIK_INSECURE: "false"
AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}
ports:
- "9101:9000"
depends_on:
- server
networks:
- authentik_internal
- proxy
networks:
authentik_internal:
internal: true
proxy:
external: true
Review payment logger au…, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: nas
SSH: nas
location-logger (Git)
location-logger
location-logger (Git) - main*, Checkout Branch/Tag...
main*
location-logger (Git) - Synchronize Changes
No Problems
0
0
No Ports Forwarded
0
Notifications
Sign In
Sign In
collapsed
Command Succeeded
Review payment logger authorization implementation
Session history
New session
Message actions
review payment_logger project how toes authorization work
Thinking
Thinking
Let me explore the payment_logger project structure first.
Bash
Find payment_logger project files
IN
find /volume2/docker -type f -name "*.py" -o -name "*.yml" -o -name "*.yaml" -o -name "*.env" -o -name "*.toml" -o -name "*.cfg" | grep -i payment | head -50
Copy code to clipboard
OUT
bfs: error: /volume2/docker/portnotedb/pg_commit_ts: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_dynshmem: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_notify: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_serial: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_snapshots: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_subtrans: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_twophase: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_multixact: Permission denied.
bfs: error: /volume2/docker/portnotedb/base: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_replslot: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_tblspc: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_stat: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_stat_tmp: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_xact: Permission denied.
bfs: error: /volume2/docker/portnotedb/pg_logical: Permission denied.
bfs: error: /volume2/docker/openttd/.dbus: Permission denied.
bfs: error: /volume2/docker/immich/db: Permission denied.
bfs: error: /volume2/docker/paperlessngx/db: Permission denied.
bfs: error: /volume2/docker/appflowy/postgres: Permission denied.
bfs: error: /volume2/docker/auth/db: Permission denied.
bfs: error: /volume2/docker/openttd/.XDG/dbus-1: Permission denied.
bfs: error: /volume2/docker/openttd/.config/pulse: Permission denied.
bfs: error: /volume2/docker/openttd/.cache/openbox/sessions: Permission denied.
/volume2/docker/payments-logger/.env
/volume2/docker/payments-logger/docker-compose.yml
/volume2/docker/payments-logger/backend/prisma/migrations/migration_lock.toml
Bash
List docker directory contents
IN
ls /volume2/docker/
Copy code to clipboard
OUT
adguard
ai-stack
app-db
appflowy
audiobookshelf
auth
beszel
bitwarden
dawarich
dsk-uploader
flask-app
garmin-connector
gitea
health
health-tracker
homarr
hst
immich
jellyfinht
kavita
libreoffice
linkwarden
location-logger
mariadb
meeting-detector
mindfulmama
n8n
notifier-app
npm
oauth
obsidian
ollama
openttd
openvpn-client
open-webui
orchestrator
outfit-app
owntracks-stack
paperlessngx
payments-logger
personal-log
personal-log-system
player
portainer
portnotedb
reminders-app
romm
second-brain
static
stirling
syncthing
tailscale
temp-logger
test-app
tmp
torrent-stack
tree
trilium
tubearchivist
twenty
uptimekuma
ytptube
Agent:
Explore payment_logger authorization code
IN
Explore the payments-logger project at /volume2/docker/payments-logger and give me a thorough understanding of how authorization works. I need to know:
1. What auth mechanism is used (JWT, sessions, API keys, OAuth, etc.)
2. Where auth is enforced (middleware, decorators, route guards, etc.)
3. What roles/permissions exist
4. How tokens are issued, validated, and refreshed
5. Any auth-related config (env vars, settings)
Please read the key source files and give me a clear summary with file paths and line numbers for the important parts.
Bash
IN
find /volume2/docker/payments-logger -type f -name "*.py" -o -name "*.json" -o -name "*.yml" -o -name "*.yaml" | grep -E "(auth|token|jwt|session|permission|role)" | head -20
Copy code to clipboard
OUT
(Bash completed with no output)
Bash
IN
ls -la /volume2/docker/payments-logger/ 2>/dev/null || echo "Directory not found"
Copy code to clipboard
OUT
total 36
drwxrwxrwx 1 Adm1n admin 162 Mar 29 18:01 .
drwxrwxrwx 1 root root 1146 Apr 26 18:49 ..
-rwxrwxrwx 1 Adm1n admin 15233 Feb 22 17:08 API.md
drwxrwxrwx 1 Adm1n admin 88 Mar 29 15:41 backend
drwxrwxrwx 1 Adm1n admin 38 Mar 29 17:07 .claude
-rwxrwxrwx 1 Adm1n admin 1502 Mar 29 18:01 docker-compose.yml
-rwxrwxrwx 1 Adm1n admin 1066 Mar 29 15:44 .env
-rwxrwxrwx 1 Adm1n admin 1078 Feb 14 17:53 .env.example
drwxrwxrwx 1 Adm1n admin 194 Mar 29 15:44 frontend
-rwxrwxrwx 1 Adm1n admin 19 Feb 14 17:54 .gitignore
-rwxrwxrwx 1 Adm1n admin 4052 Feb 14 19:06 README.md
Bash
IN
find /volume2/docker/payments-logger/backend -type f | head -30
Copy code to clipboard
OUT
/volume2/docker/payments-logger/backend/Dockerfile
/volume2/docker/payments-logger/backend/.dockerignore
/volume2/docker/payments-logger/backend/package.json
/volume2/docker/payments-logger/backend/prisma/schema.prisma
/volume2/docker/payments-logger/backend/src/parser.js
/volume2/docker/payments-logger/backend/src/index.js
/volume2/docker/payments-logger/backend/src/auth.js
/volume2/docker/payments-logger/backend/prisma/migrations/migration_lock.toml
/volume2/docker/payments-logger/backend/src/routes/payments.js
/volume2/docker/payments-logger/backend/prisma/migrations/20260210_init/migration.sql
/volume2/docker/payments-logger/backend/prisma/migrations/20260210_simplify/migration.sql
/volume2/docker/payments-logger/backend/prisma/migrations/20260222_add_card/migration.sql
Bash
IN
find /volume2/docker/payments-logger -type f \( -name "*.js" -o -name "*.json" -o -name "*.md" \) | sort
Copy code to clipboard
OUT
/volume2/docker/payments-logger/API.md
/volume2/docker/payments-logger/backend/package.json
/volume2/docker/payments-logger/backend/src/auth.js
/volume2/docker/payments-logger/backend/src/index.js
/volume2/docker/payments-logger/backend/src/parser.js
/volume2/docker/payments-logger/backend/src/routes/payments.js
/volume2/docker/payments-logger/.claude/settings.local.json
/volume2/docker/payments-logger/frontend/package.json
/volume2/docker/payments-logger/frontend/postcss.config.js
/volume2/docker/payments-logger/frontend/src/auth.js
/volume2/docker/payments-logger/frontend/tailwind.config.js
/volume2/docker/payments-logger/frontend/vite.config.js
/volume2/docker/payments-logger/README.md
Read
.env
.env
Read
auth.js
auth.js
Read
index.js
index.js
Read
package.json
package.json
Read
auth.js
auth.js
Read
API.md
API.md
Read
payments.js
payments.js
Read
.env.example
.env.example
Read
schema.prisma
schema.prisma
Bash
IN
grep -r "API_KEY\|auth\|token\|oauth\|hydra" /volume2/docker/payments-logger/backend/src --include="*.js" -n
Copy code to clipboard
OUT
/volume2/docker/payments-logger/backend/src/index.js:6:const { bearerTokenMiddleware, wellKnownRouter } = require('./auth');
/volume2/docker/payments-logger/backend/src/index.js:18:// ── OAuth Bearer token auth (skips public paths) ──────────────────────────────
/volume2/docker/payments-logger/backend/src/auth.js:2: * OAuth 2.1 / Hydra JWT authentication for Express.
/volume2/docker/payments-logger/backend/src/auth.js:6: * - wellKnownRouter — serves /.well-known/oauth-* discovery endpoints
/volume2/docker/payments-logger/backend/src/auth.js:33:function sendUnauthorized(res, detail, error = 'invalid_token') {
/volume2/docker/payments-logger/backend/src/auth.js:39: `resource_metadata="${realm}/.well-known/oauth-protected-resource"`,
/volume2/docker/payments-logger/backend/src/auth.js:40: `authorization_server="${HYDRA_PUBLIC_URL}"`,
/volume2/docker/payments-logger/backend/src/auth.js:52: * On success, attaches the decoded payload to req.tokenPayload.
/volume2/docker/payments-logger/backend/src/auth.js:54: * @param {Set<string>} publicPaths Paths to skip auth for.
/volume2/docker/payments-logger/backend/src/auth.js:58: '/.well-known/oauth-protected-resource',
/volume2/docker/payments-logger/backend/src/auth.js:59: '/.well-known/oauth-authorization-server',
/volume2/docker/payments-logger/backend/src/auth.js:66: const auth = req.headers.authorization || '';
/volume2/docker/payments-logger/backend/src/auth.js:67: if (!auth.toLowerCase().startsWith('bearer ')) {
/volume2/docker/payments-logger/backend/src/auth.js:68: return sendUnauthorized(res, 'Bearer token required', 'invalid_request');
/volume2/docker/payments-logger/backend/src/auth.js:71: const token = auth.slice(7).trim();
/volume2/docker/payments-logger/backend/src/auth.js:72: if (!token) {
/volume2/docker/payments-logger/backend/src/auth.js:73: return sendUnauthorized(res, 'Bearer token required', 'invalid_request');
/volume2/docker/payments-logger/backend/src/auth.js:82: const { payload } = await jwtVerify(token, getJwks(), verifyOptions);
/volume2/docker/payments-logger/backend/src/auth.js:83: req.tokenPayload = payload;
/volume2/docker/payments-logger/backend/src/auth.js:87: const error = msg.includes('expired') ? 'invalid_token' : 'invalid_token';
/volume2/docker/payments-logger/backend/src/auth.js:88: sendUnauthorized(res, msg, error);
/volume2/docker/payments-logger/backend/src/auth.js:98:wellKnownRouter.get('/.well-known/oauth-protected-resource', (_req, res) => {
/volume2/docker/payments-logger/backend/src/auth.js:103: authorization_servers: [HYDRA_PUBLIC_URL],
/volume2/docker/payments-logger/backend/src/auth.js:111:wellKnownRouter.get('/.well-known/oauth-authorization-server', async (_req, res) => {
/volume2/docker/payments-logger/backend/src/auth.js:119: authorization_endpoint: doc.authorization_endpoint,
/volume2/docker/payments-logger/backend/src/auth.js:120: token_endpoint: doc.token_endpoint,
/volume2/docker/payments-logger/backend/src/auth.js:123: grant_types_supported: doc.grant_types_supported || ['authorization_code', 'refresh_token'],
/volume2/docker/payments-logger/backend/src/auth.js:124: [API_KEY]: doc.[API_KEY] || ['none', 'client_secret_basic'],
/volume2/docker/payments-logger/backend/src/auth.js:128: id_token_signing_alg_values_supported: doc.id_token_signing_alg_values_supported || ['RS256'],
/volume2/docker/payments-logger/backend/src/routes/payments.js:58:// ── Ingest a payment (public — no auth) ──────────────────────────────────────
Bash
IN
find /volume2/docker/payments-logger/frontend/src -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | head -20
Copy code to clipboard
OUT
/volume2/docker/payments-logger/frontend/src/main.jsx
/volume2/docker/payments-logger/frontend/src/App.jsx
/volume2/docker/payments-logger/frontend/src/auth.js
/volume2/docker/payments-logger/frontend/src/components/PaymentCard.jsx
/volume2/docker/payments-logger/frontend/src/components/PaymentList.jsx
/volume2/docker/payments-logger/frontend/src/components/FilterBar.jsx
/volume2/docker/payments-logger/frontend/src/components/PaymentTable.jsx
/volume2/docker/payments-logger/frontend/src/components/AuthProvider.jsx
/volume2/docker/payments-logger/frontend/src/components/AuthCallback.jsx
Read
AuthProvider.jsx
AuthProvider.jsx
Read
AuthCallback.jsx
AuthCallback.jsx
Read
App.jsx
App.jsx
Read
main.jsx
main.jsx
Read
vite.config.js
vite.config.js
Bash
IN
grep -r "HYDRA\|VITE" /volume2/docker/payments-logger --include=".env*" -n
Copy code to clipboard
OUT
(Bash completed with no output)
Read
docker-compose.yml
docker-compose.yml
Bash
IN
grep -r "API_KEY" /volume2/docker/payments-logger/backend --include="*.js" -n
Copy code to clipboard
OUT
(Bash completed with no output)
Read
README.md
README.md
Bash
IN
grep -n "HYDRA\|oauth\|TOKEN" /volume2/docker/payments-logger/backend/src/index.js /volume2/docker/payments-logger/backend/src/auth.js | head -40
Copy code to clipboard
OUT
/volume2/docker/payments-logger/backend/src/auth.js:6: * - wellKnownRouter — serves /.well-known/oauth-* discovery endpoints
/volume2/docker/payments-logger/backend/src/auth.js:11:const HYDRA_PUBLIC_URL = (process.env.HYDRA_PUBLIC_URL || '').replace(/\/$/, '');
/volume2/docker/payments-logger/backend/src/auth.js:24: new URL(`${HYDRA_PUBLIC_URL}/.well-known/jwks.json`)
/volume2/docker/payments-logger/backend/src/auth.js:39: `resource_metadata="${realm}/.well-known/oauth-protected-resource"`,
/volume2/docker/payments-logger/backend/src/auth.js:40: `authorization_server="${HYDRA_PUBLIC_URL}"`,
/volume2/docker/payments-logger/backend/src/auth.js:58: '/.well-known/oauth-protected-resource',
/volume2/docker/payments-logger/backend/src/auth.js:59: '/.well-known/oauth-authorization-server',
/volume2/docker/payments-logger/backend/src/auth.js:78: issuer: HYDRA_PUBLIC_URL,
/volume2/docker/payments-logger/backend/src/auth.js:81: if (process.env.TOKEN_AUDIENCE) verifyOptions.audience = process.env.TOKEN_AUDIENCE;
/volume2/docker/payments-logger/backend/src/auth.js:98:wellKnownRouter.get('/.well-known/oauth-protected-resource', (_req, res) => {
/volume2/docker/payments-logger/backend/src/auth.js:103: authorization_servers: [HYDRA_PUBLIC_URL],
/volume2/docker/payments-logger/backend/src/auth.js:107: jwks_uri: `${HYDRA_PUBLIC_URL}/.well-known/jwks.json`,
/volume2/docker/payments-logger/backend/src/auth.js:111:wellKnownRouter.get('/.well-known/oauth-authorization-server', async (_req, res) => {
/volume2/docker/payments-logger/backend/src/auth.js:113: const r = await fetch(`${HYDRA_PUBLIC_URL}/.well-known/openid-configuration`);
/volume2/docker/payments-logger/backend/src/auth.js:118: issuer: doc.issuer || HYDRA_PUBLIC_URL,
Thinking
Thinking
payments-logger Authorization Overview
payments-logger Authorization Overview
The project uses
OAuth 2.1 with PKCE
via an external Hydra OAuth server at
hydra.lakylak.xyz
.
Auth Flow
Auth Flow
Frontend
(
frontend/src/auth.js
frontend/src/auth.js
):
Fetches OAuth server metadata via discovery endpoint
Generates a PKCE code verifier/challenge (SHA-256)
Redirects user to Hydra login with
code_challenge
On callback, exchanges code + verifier for tokens
Stores
access_token
,
refresh_token
in
localStorage
(
pl_oauth_tokens
)
Auto-refreshes token 30 seconds before expiry
Backend
(
backend/src/auth.js
backend/src/auth.js
):
bearerTokenMiddleware
validates the
Authorization: Bearer <token>
header
Fetches Hydra's JWKS (cached 300s) and verifies JWT signature (RS256/ES256/PS256)
Validates issuer (
[URL_WITH_CREDENTIALS]
const prisma = new PrismaClient();
const [ENV_SECRET];
const JWT_EXPIRE_MINS = parseInt(process.env.JWT_EXPIRE_MINUTES || '1440', 10);
if (!JWT_SECRET) {
console.error('FATAL: JWT_SECRET env var is required');
process.exit(1);
}
const secret = new TextEncoder().encode(JWT_SECRET);
// ── JWT helpers ───────────────────────────────────────────────────────────────
async function signToken(username) {
return new SignJWT({ sub: username })
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime(`${JWT_EXPIRE_MINS}m`)
.sign(secret);
}
async function verifyToken(token) {
const { payload } = await jwtVerify(token, secret, { algorithms: ['HS256'] });
return payload;
}
// ── Middleware ────────────────────────────────────────────────────────────────
function bearerTokenMiddleware(publicPaths) {
const _public = new Set(publicPaths);
return async (req, res, next) => {
if (_public.has(req.path)) return next();
const auth = req.headers.authorization || '';
if (!auth.toLowerCase().startsWith('bearer ')) {
return res.status(401).json({ error: 'Bearer token required' });
}
const token = auth.slice(7).trim();
try {
req.tokenPayload = await verifyToken(token);
next();
} catch (err) {
res.status(401).json({ error: 'Invalid or expired token' });
}
};
}
// ── Auth routes ───────────────────────────────────────────────────────────────
const authRouter = express.Router();
authRouter.post('/auth/register', async (req, res) => {
const { username, password } = req.body || {};
if (!username || !password) {
return res.status(400).json({ error: 'username and password are required' });
}
if (typeof username !== 'string' || username.length > 100) {
return res.status(400).json({ error: 'username must be a string under 100 chars' });
}
if (typeof password !== 'string' || password.length < 8) {
return res.status(400).json({ error: 'password must be at least 8 characters' });
}
try {
const existing = await prisma.user.findUnique({ where: { username } });
if (existing) {
return res.status(409).json({ error: 'Username already taken' });
}
const hashedPassword = [PASSWORD] bcrypt.hash(password, 10);
await prisma.user.create({ data: { username, hashedPassword } });
const token = await signToken(username);
res.status(201).json({ access_token: token, token_type: 'bearer', expires_in: JWT_EXPIRE_MINS * 60 });
} catch (err) {
console.error('Register error:', err);
res.status(500).json({ error: 'Registration failed' });
}
});
authRouter.post('/auth/login', async (req, res) => {
const { username, password } = req.body || {};
if (!username || !password) {
return res.status(400).json({ error: 'username and password are required' });
}
try {
const user = await prisma.user.findUnique({ where: { username } });
// Always run bcrypt compare to prevent timing-based username enumeration
const dummyHash = '$2a$10$abcdefghijklmnopqrstuuABCDEFGHIJKLMNOPQRSTUVWXYZ012345';
const valid = user
? await bcrypt.compare(password, user.hashedPassword)
: await bcrypt.compare(password, dummyHash).then(() => false);
if (!valid) {
return res.status(401).json({ error: 'Invalid username or password' });
}
const token = await signToken(username);
res.json({ access_token: token, token_type: 'bearer', expires_in: JWT_EXPIRE_MINS * 60 });
} catch (err) {
console.error('Login error:', err);
res.status(500).json({ error: 'Login failed' });
}
});
module.exports = { bearerTokenMiddleware, authRouter };
Update Todos
Add bcryptjs to backend package.json
Rewrite backend/src/auth.js (HS256 JWT + bcrypt, login/register routes)
Update backend/src/index.js (remove wellKnownRouter, mount authRouter)
Add User model to prisma/schema.prisma
Create Prisma migration for users table
Rewrite frontend/src/auth.js (simple username/password login)
Rewrite frontend/src/components/AuthProvider.jsx (login form instead of PKCE redirect)
Update frontend/src/main.jsx (remove /auth/callback handling)
Delete frontend/src/components/AuthCallback.jsx
Update frontend/vite.config.js (remove /.well-known proxy)...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
412
|
19
|
14
|
2026-05-07T07:09:50.344933+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778137790344_m1.jpg...
|
Firefox
|
Platform Sprint 3 Q2 - Platform Team - Scrum Board Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira — Work...
|
True
|
jiminny.atlassian.net/jira/software/c/projects/JY/ jiminny.atlassian.net/jira/software/c/projects/JY/boards/37...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 3 Q2 - Platform Team - Scrum Board Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Close tab
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Jy 20807 check various issues with stages by nikolaybiaivanov · Pull Request #12041 · jiminny/app
Jy 20807 check various issues with stages by nikolaybiaivanov · Pull Request #12041 · jiminny/app
Sentry
Sentry
Pull requests · jiminny/app
Pull requests · jiminny/app
Userpilot | Ask Jiminny Report Generated
Userpilot | Ask Jiminny Report Generated
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Service requests
Service requests
Create
Create
More for service requests
More for service requests
Incidents
Incidents
Create
Create
More for incidents
More for incidents
Reports
Reports
More actions for reports
More actions for reports
Operations
Operations
More actions for operations
More actions for operations
Knowledge Base
Knowledge Base
More actions for knowledge base
More actions for knowledge base
Customers
Customers
More actions for customers
More actions for customers
Channels
Channels
Email logs
Email logs
More actions for customer notification logs
More actions for customer notification logs
Developer escalations
Developer escalations
More actions for developer escalations
More actions for developer escalations
Slack integration
Slack integration
More actions for Slack integration...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"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,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 20807 check various issues with stages by nikolaybiaivanov · Pull Request #12041 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20807 check various issues with stages by nikolaybiaivanov · Pull Request #12041 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Ask Jiminny Report Generated","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Ask Jiminny Report Generated","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"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.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.0,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to:","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Space navigation","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Space navigation","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar [","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar [","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Switch sites or apps","depth":10,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to your Jira homepage","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":10,"on_screen":true,"help_text":"","placeholder":"Search","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notifications","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Notifications","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":12,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recent","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recent","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Starred","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Starred","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Apps","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Apps","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Apps","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Spaces","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Spaces","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create space","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create space","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for spaces","depth":13,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for spaces","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recent","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny (New)","depth":17,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny (New)","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny (New)","depth":18,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXMenuButton","text":"Create board","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create board","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Jiminny (New)","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Jiminny (New)","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Platform Team","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Team","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Capture Team","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Capture Team","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Enterprise Stability Issues 🤕","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enterprise Stability Issues 🤕","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Processing Team","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Processing Team","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SE Kanban","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SE Kanban","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Board actions","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Board actions","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service-Desk","depth":17,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Service-Desk","depth":20,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Service-Desk","depth":18,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for Service-Desk","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Queues","depth":21,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Queues","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":22,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for queues","depth":22,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for queues","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Service requests","depth":21,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Service requests","depth":24,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":22,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for service requests","depth":22,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for service requests","depth":24,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Incidents","depth":22,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Incidents","depth":25,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create","depth":23,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More for incidents","depth":23,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More for incidents","depth":25,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reports","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reports","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for reports","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for reports","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Operations","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Operations","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for operations","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for operations","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Knowledge Base","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Knowledge Base","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for knowledge base","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for knowledge base","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for customers","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for customers","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Channels","depth":19,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Channels","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Email logs","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Email logs","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for customer notification logs","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for customer notification logs","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Developer escalations","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Developer escalations","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for developer escalations","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions for developer escalations","depth":22,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Slack integration","depth":19,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Slack integration","depth":22,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions for Slack integration","depth":20,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9076856145665045788
|
148967385328145632
|
click
|
accessibility
|
NULL
|
Platform Sprint 3 Q2 - Platform Team - Scrum Board Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 3 Q2 - Platform Team - Scrum Board - Jira
Close tab
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Jy 20807 check various issues with stages by nikolaybiaivanov · Pull Request #12041 · jiminny/app
Jy 20807 check various issues with stages by nikolaybiaivanov · Pull Request #12041 · jiminny/app
Sentry
Sentry
Pull requests · jiminny/app
Pull requests · jiminny/app
Userpilot | Ask Jiminny Report Generated
Userpilot | Ask Jiminny Report Generated
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Space navigation
Space navigation
Collapse sidebar [
Collapse sidebar [
Switch sites or apps
Switch sites or apps
Go to your Jira homepage
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
Settings
Settings
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Apps
Apps
More actions for Apps
More actions for Apps
Spaces
Spaces
Create space
Create space
More actions for spaces
More actions for spaces
Recent
Jiminny (New)
Jiminny (New)
Jiminny (New)
Create board
Create board
More actions for Jiminny (New)
More actions for Jiminny (New)
Platform Team
Platform Team
Board actions
Board actions
Capture Team
Capture Team
Board actions
Board actions
Enterprise Stability Issues 🤕
Enterprise Stability Issues 🤕
Board actions
Board actions
Processing Team
Processing Team
Board actions
Board actions
SE Kanban
SE Kanban
Board actions
Board actions
Service-Desk
Service-Desk
More actions for Service-Desk
More actions for Service-Desk
Queues
Queues
Create
Create
More for queues
More for queues
Service requests
Service requests
Create
Create
More for service requests
More for service requests
Incidents
Incidents
Create
Create
More for incidents
More for incidents
Reports
Reports
More actions for reports
More actions for reports
Operations
Operations
More actions for operations
More actions for operations
Knowledge Base
Knowledge Base
More actions for knowledge base
More actions for knowledge base
Customers
Customers
More actions for customers
More actions for customers
Channels
Channels
Email logs
Email logs
More actions for customer notification logs
More actions for customer notification logs
Developer escalations
Developer escalations
More actions for developer escalations
More actions for developer escalations
Slack integration
Slack integration
More actions for Slack integration...
|
411
|
NULL
|
NULL
|
NULL
|
|
10257
|
470
|
17
|
2026-05-08T17:15:21.656867+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-08/1778 /Users/lukas/.screenpipe/data/data/2026-05-08/1778260521656_m2.jpg...
|
Firefox
|
Sign in – Google accounts — Personal
|
True
|
accounts.google.com/v3/signin/accountchooser?acces accounts.google.com/v3/signin/accountchooser?access_type=offline&client_id=690608236388-k8tg5kmb75o295ati2g86n6v8hqbg2f5.apps.googleusercontent.com&prompt=select_account&redirect_uri=https%3A%2F%2Fapp.affine.pro%2Foauth%2Fcallback&response_type=code&scope=openid+email+profile&state=%7B%22state%22%3A%22410a2e2a-54b1-451b-9cbb-857afe60df29%22%2C%22client%22%3A%22web%22%2C%22provider%22%3A%22Google%22%7D&dsh=S-1976060048%3A1778260522005265&o2v=2&service=lso&flowName=GeneralOAuthFlow&opparams=%253F&continue=https%3A%2F%2Faccounts.google.com%2Fsignin%2Foauth%2Fconsent%3Fauthuser%3Dunknown%26part%3DAJi8hAM58lT2LRrzsqMapDofd2EsvdgUmVHjBsIbrweHpVa1pl3nLtQm7lrmsjfb5LJIFjud3n3Gt5btrganRWzfGQBG8Hy2Hmiuq-m44ytRH1MgHouqWuwskGdsZ36qL0SxGpBqqoWhfis4bSe2cHzE9RCpB3Zhwx5aOnRZE6qDB-jLagzxdl49nD2Dy99QijV2nplwqnzNiJe8vb3lgTdbaVOqocy2cPRgBDyws_Z9wvtqno63icCiZY1VvXKFOt9s5_DKZgTsjyeURu9gTUvm05kChU9P7SAtbL_SXSM4-eTzmj-HoLh52TjqbTuJbdvkem9jJWDRbIPuaQc-6E5SFURiaWQ4FnWVo7fqiQLhResS83g2ZI5hpIAcjYG1r04d4UYizvDbGrd2ZAMTTZFbpTOFDaMl27IixZ-rUYZ0O4vGKkqULTykQNgWGOS72-LMerwmm29Mksktwt1cq74PFuv-l1KxsA%26flowName%3DGeneralOAuthFlow%26as%3DS-1976060048%253A1778260522005265%26client_id%3D690608236388-k8tg5kmb75o295ati2g86n6v8hqbg2f5.apps.googleusercontent.com%26requestPath%3D%252Fsignin%252Foauth%252Fconsent%23&app_domain=https%3A%2F%2Fapp.affine.pro...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Sign in with Google
Choose an account
Choose an ac Sign in with Google
Choose an account
Choose an account
to continue to
AFFiNE
Lukáš Koválik [EMAIL]
Lukáš Koválik
[EMAIL]
Lukas [EMAIL]
Lukas
[EMAIL]
Use another account
Use another account
Before using this app, you can review AFFiNE’s
Privacy Policy
Privacy Policy
and Terms of Service.
English (United Kingdom)
English (United Kingdom)
Help
Help
Privacy
Privacy
Terms
Terms
Read www.gstatic.com...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Sign in with Google","depth":11,"bounds":{"left":0.46625665,"top":0.35913807,"width":0.042220745,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Choose an account","depth":10,"bounds":{"left":0.46226728,"top":0.4688747,"width":0.15292554,"height":0.0415004},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Choose an account","depth":11,"bounds":{"left":0.46226728,"top":0.46727854,"width":0.12849069,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to continue to","depth":11,"bounds":{"left":0.46226728,"top":0.52474064,"width":0.03474069,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"AFFiNE","depth":11,"bounds":{"left":0.49700797,"top":0.52474064,"width":0.018450798,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Lukáš Koválik kovaliklukas@gmail.com","depth":14,"bounds":{"left":0.6258311,"top":0.43056664,"width":0.16356383,"height":0.054269753},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lukáš Koválik","depth":16,"bounds":{"left":0.64444816,"top":0.44173983,"width":0.03357713,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"kovaliklukas@gmail.com","depth":16,"bounds":{"left":0.64444816,"top":0.46009576,"width":0.050531916,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Lukas lukakovalik@gmail.com","depth":14,"bounds":{"left":0.6258311,"top":0.48563448,"width":0.16356383,"height":0.054269753},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lukas","depth":16,"bounds":{"left":0.64444816,"top":0.49680766,"width":0.01462766,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lukakovalik@gmail.com","depth":16,"bounds":{"left":0.64444816,"top":0.5151636,"width":0.04837101,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Use another account","depth":14,"bounds":{"left":0.6258311,"top":0.54070234,"width":0.16356383,"height":0.0415004},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Use another account","depth":16,"bounds":{"left":0.64444816,"top":0.5534717,"width":0.052027926,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Before using this app, you can review AFFiNE’s","depth":10,"bounds":{"left":0.63115025,"top":0.61652035,"width":0.09906915,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy Policy","depth":10,"bounds":{"left":0.7302194,"top":0.61652035,"width":0.031416222,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy Policy","depth":11,"bounds":{"left":0.7302194,"top":0.61652035,"width":0.031416222,"height":0.014764565},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and Terms of Service.","depth":10,"bounds":{"left":0.63115025,"top":0.61652035,"width":0.13962767,"height":0.030726258},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"English (United Kingdom)","depth":10,"bounds":{"left":0.4502992,"top":0.6915403,"width":0.06632314,"height":0.025538707},"on_screen":true,"value":"English (United Kingdom)","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"English (United Kingdom)","depth":12,"bounds":{"left":0.45561835,"top":0.698324,"width":0.04637633,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Help","depth":11,"bounds":{"left":0.73254657,"top":0.68515563,"width":0.016456118,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":12,"bounds":{"left":0.7365359,"top":0.698324,"width":0.008477394,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy","depth":11,"bounds":{"left":0.75166225,"top":0.68515563,"width":0.021276595,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy","depth":12,"bounds":{"left":0.7556516,"top":0.698324,"width":0.013297873,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms","depth":11,"bounds":{"left":0.7755984,"top":0.68515563,"width":0.019115692,"height":0.03830806},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms","depth":12,"bounds":{"left":0.77958775,"top":0.698324,"width":0.011136968,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Read www.gstatic.com","depth":5,"bounds":{"left":0.2549867,"top":0.9876297,"width":0.03956117,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9076739865190569649
|
-4837997082525155844
|
visual_change
|
accessibility
|
NULL
|
Sign in with Google
Choose an account
Choose an ac Sign in with Google
Choose an account
Choose an account
to continue to
AFFiNE
Lukáš Koválik [EMAIL]
Lukáš Koválik
[EMAIL]
Lukas [EMAIL]
Lukas
[EMAIL]
Use another account
Use another account
Before using this app, you can review AFFiNE’s
Privacy Policy
Privacy Policy
and Terms of Service.
English (United Kingdom)
English (United Kingdom)
Help
Help
Privacy
Privacy
Terms
Terms
Read www.gstatic.com...
|
10255
|
NULL
|
NULL
|
NULL
|
|
19950
|
858
|
10
|
2026-05-11T14:14:48.675765+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778508888675_m1.jpg...
|
Firefox
|
All docs · AFFiNE — Personal
|
True
|
app.affine.pro/workspace/M_vDJhnmiED_6JNdL9GEq/all
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
New Tab
New Tab
Screenpipe — Archive
Screenpipe — New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
All docs · AFFiNE
All docs · AFFiNE
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Open this doc in AFFiNE app
Don't have the app?
Click to download
Click to download
.
Remember choice
Remember choice
Remember choice
Dismiss
Dismiss
Open in app
Open in app
Demo Workspace Syncing...
Demo Workspace
Syncing...
Lukáš Koválik
Search
All docs
All docs
Journals
Journals
Notifications
Intelligence
Intelligence
Settings
Favorites
Favorites
No favorites
Organize
Organize
First Folder
How to use folder and Tags
How to use folder and Tags
Tags
Tags
Collections
Collections
Others
Others
Trash
Trash
Import
Template
Learn more
Learn more
Download App
Download App
Docs
Docs
Collections
Collections
Tags
Tags
Display
Display
New doc
New doc
All
May 8, 2026...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"All docs · AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"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.05590278,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.078819446,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.10208333,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.12534723,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.14861111,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open this doc in AFFiNE app","depth":8,"bounds":{"left":0.79965276,"top":0.115,"width":0.13194445,"height":0.019444445},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Don't have the app?","depth":9,"bounds":{"left":0.79965276,"top":0.14222223,"width":0.08090278,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Click to download","depth":9,"bounds":{"left":0.88055557,"top":0.14222223,"width":0.07048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Click to download","depth":10,"bounds":{"left":0.88055557,"top":0.14222223,"width":0.07048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":9,"bounds":{"left":0.95104164,"top":0.14222223,"width":0.0020833334,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Remember choice","depth":9,"bounds":{"left":0.79965276,"top":0.1711111,"width":0.013888889,"height":0.022222223},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Remember choice","depth":10,"bounds":{"left":0.79965276,"top":0.1711111,"width":0.013888889,"height":0.022222223},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Remember choice","depth":9,"bounds":{"left":0.81631947,"top":0.17388889,"width":0.071875,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss","depth":8,"bounds":{"left":0.934375,"top":0.16777778,"width":0.04826389,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dismiss","depth":10,"bounds":{"left":0.94340277,"top":0.17388889,"width":0.030208332,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open in app","depth":8,"bounds":{"left":0.98541665,"top":0.16777778,"width":0.014583349,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open in app","depth":10,"bounds":{"left":0.99444443,"top":0.17388889,"width":0.00555557,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Demo Workspace Syncing...","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Demo Workspace","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Syncing...","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lukáš Koválik","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Search","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"All docs","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All docs","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Journals","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Journals","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Notifications","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intelligence","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intelligence","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Settings","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Favorites","depth":10,"on_screen":true,"help_text":"","role_description":"switch","subrole":"AXSwitch","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorites","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No favorites","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Organize","depth":10,"on_screen":true,"help_text":"","role_description":"switch","subrole":"AXSwitch","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Organize","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"First Folder","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"How to use folder and Tags","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to use folder and Tags","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Tags","depth":10,"on_screen":true,"help_text":"","role_description":"switch","subrole":"AXSwitch","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Tags","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Collections","depth":10,"on_screen":true,"help_text":"","role_description":"switch","subrole":"AXSwitch","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collections","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Others","depth":10,"on_screen":true,"help_text":"","role_description":"switch","subrole":"AXSwitch","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Others","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Trash","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Trash","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Template","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Download App","depth":9,"bounds":{"left":0.29722223,"top":0.0,"width":0.15243055,"height":0.057777777},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Download App","depth":11,"bounds":{"left":0.33958334,"top":0.0,"width":0.06701389,"height":0.019444445},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Docs","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Docs","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Collections","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collections","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Tags","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Tags","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Display","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Display","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New doc","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New doc","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"All","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"May 8, 2026","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9075048376904643652
|
-7469256773195430329
|
click
|
accessibility
|
NULL
|
New Tab
New Tab
Screenpipe — Archive
Screenpipe — New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
All docs · AFFiNE
All docs · AFFiNE
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Open this doc in AFFiNE app
Don't have the app?
Click to download
Click to download
.
Remember choice
Remember choice
Remember choice
Dismiss
Dismiss
Open in app
Open in app
Demo Workspace Syncing...
Demo Workspace
Syncing...
Lukáš Koválik
Search
All docs
All docs
Journals
Journals
Notifications
Intelligence
Intelligence
Settings
Favorites
Favorites
No favorites
Organize
Organize
First Folder
How to use folder and Tags
How to use folder and Tags
Tags
Tags
Collections
Collections
Others
Others
Trash
Trash
Import
Template
Learn more
Learn more
Download App
Download App
Docs
Docs
Collections
Collections
Tags
Tags
Display
Display
New doc
New doc
All
May 8, 2026...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
1034
|
37
|
32
|
2026-05-07T07:57:04.069575+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778140624069_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Code changed:
Hide
Sync Changes
Hide This Notification
37
1
35
63
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
Sync Changes
Hide This Notification
Code changed:
Hide
8
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Activity\RingCentral;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Cache\RateLimiter;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Jiminny\DTO\ImportCall\RingCentral\Extension;
use Jiminny\Exceptions\ApiResponseException;
use Jiminny\Exceptions\HttpBadRequestException;
use Jiminny\Exceptions\HttpForbiddenException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Exceptions\QuotaExceededException;
use Jiminny\Exceptions\RingCentralException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\SocialAccount;
use Jiminny\Services\Activity\ActivityProviderClient;
use League\OAuth2\Client\Token\AccessTokenInterface;
use Psr\Http\Message\ResponseInterface;
use RingCentral\SDK\Http\ApiException;
use RingCentral\SDK\Http\ApiResponse;
use RingCentral\SDK\SDK;
use Sentry;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class Client extends ActivityProviderClient
{
public const RINGCENTRAL_HEAVY_REQUEST_LIMIT_WINDOW = 60;
private const ENDPOINT_EXTENSION_LIST = '/restapi/v1.0/account/~/extension';
private const EXTENSION_LIST_MAX_RETRIES = 10;
private RateLimiter $rateLimiter;
public function __construct(?array $config)
{
parent::__construct($config);
$this->rateLimiter = app(RateLimiter::class);
}
public function get(string $url, array $data = [])
{
return $this->requestWithAutomaticReauthorize('GET', $url, $data);
}
/**
* Make a request to the endpoint.
*
* @param $method
* @param $endpoint
* @param array $options
*
* @throws ApiResponseException
* @throws HttpBadRequestException
* @throws HttpForbiddenException
* @throws HttpNotFoundException
* @throws QuotaExceededException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function request($method, $endpoint, array $options = [])
{
$this->checkExpiredToken();
$client = $this->getSdk()->platform();
$client->auth()->setData([
'access_token' => $this->accessToken,
'refresh_token' => $this->socialAccount->provider_refresh_token,
'expire_time' => $this->socialAccount->expires,
'expires_in' => $this->socialAccount->expires,
'token_type' => 'Bearer',
'refresh_token_expire_time' => $this->socialAccount->refresh_token_expires,
]);
try {
if (! $client->auth()->accessTokenValid()) {
/** @var AccessTokenInterface $accessToken */
$accessToken = $this->socialAccountService->refreshToken($this->socialAccount);
// Due to the type definition of "$this->accessToken" as string,
// the local class attribute will be cast to string via "__toString"
$this->accessToken = $accessToken->getToken();
$client->auth()->reset();
$client->auth()->setData([
'access_token' => $accessToken->getToken(),
'refresh_token' => $accessToken->getRefreshToken(),
'expire_time' => $accessToken->getExpires(),
'token_type' => 'Bearer',
]);
}
} catch (Exception $ex) {
Sentry::captureException($ex);
$this->socialAccount->state = SocialAccount::STATE_FULL_REFRESH_REQUIRED;
$this->socialAccount->save();
throw new SocialAccountTokenInvalidException($ex->getMessage());
}
try {
$headers = ['Authorization' => $this->getAuthHeader()];
if ($method === 'POST') {
$headers['Accept'] = 'application/json';
$headers['Content-Type'] = 'application/json';
/** @var ApiResponse $apiResponse */
$apiResponse = $client->$method($endpoint, $options, [], $headers, []);
return $apiResponse->jsonArray();
}
/** @var ApiResponse $apiResponse */
$apiResponse = $client->$method($endpoint, $options, $headers, []);
if (stripos($endpoint, '/call-log') !== false) {
$limitKey = ThrottleHandler::getCallLogLimitKey($this->socialAccount);
$this->setRateLimitFromHeader($apiResponse->response(), $limitKey);
}
Datadog::increment('ringcentral.requests', 1, [
'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),
'status' => 'success',
'source' => 'client',
]);
// Response could be either null or containing at least data property.
return $apiResponse->jsonArray();
} catch (ApiException $apiException) {
$errorCode = $apiException->getCode();
$errorMessage = $apiException->getMessage();
// Set social account state to full refresh
if ($errorCode === Response::HTTP_FORBIDDEN) {
$this->invalidateSocialAccount();
}
Sentry::captureException($apiException);
Datadog::increment('ringcentral.requests', 1, [
'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),
'status' => Response::$statusTexts[$errorCode],
'source' => 'client',
]);
throw new ApiResponseException($errorMessage, $errorCode, $apiException);
} catch (Exception $e) {
Sentry::captureException($e);
throw new ApiResponseException($e->getMessage());
}
}
private function invalidateSocialAccount(): void
{
$this->socialAccount->update(['state' => SocialAccount::STATE_FULL_REFRESH_REQUIRED]);
}
private function checkExpiredToken(): void
{
if ($this->socialAccount->refresh_token_expires < time()) {
$this->invalidateSocialAccount();
throw new SocialAccountTokenInvalidException('Token has expired');
}
}
private function getSDK(): SDK
{
return new SDK(
config('services.ringcentral.clientId'),
config('services.ringcentral.clientSecret'),
SDK::SERVER_PRODUCTION,
);
}
// cache the rate limit header value for 1 day
private function setRateLimitFromHeader(ResponseInterface $response, string $limitKey): void
{
if (Cache::has($limitKey)) {
return;
}
try {
$rateLimitHeader = $response->getHeader('X-Rate-Limit-Limit');
$rateLimit = reset($rateLimitHeader);
if (! empty($rateLimit)) {
$rateLimit = (int) $rateLimit;
Cache::put($limitKey, $rateLimit, now()->addHours(24));
$this->logger->info('[RingCentral] Set Rate limit from header', [
'limit_key' => $limitKey,
'rate_limit' => $rateLimit,
]);
} else {
$this->logger->error('[RingCentral] Rate limit header not found', ['limit_key' => $limitKey]);
}
} catch (Throwable $exception) {
$this->logger->error('[RingCentral] Get Rate limit header error', [
'limit_key' => $limitKey,
'exception' => $exception->getMessage(),
]);
}
}
/**
* @throws HttpNotFoundException
* @throws \JsonException
* @throws QuotaExceededException
* @throws HttpForbiddenException
* @throws RingCentralException
* @throws ServiceUnavailableException
* @throws SocialAccountTokenInvalidException
* @throws HttpBadRequestException
*/
public function getCompanyExtensions(): Collection
{
$extensions = new Collection();
$payload = [
'perPage' => 1000,
'page' => 1,
'type' => [Extension::TYPE_USER, Extension::TYPE_DEPARTMENT],
];
for ($page = 1; $page <= self::EXTENSION_LIST_MAX_RETRIES; $page++) {
$payload['page'] = $page;
$response = $this->get(self::ENDPOINT_EXTENSION_LIST, $payload);
if (
! is_array($response)
|| ! array_key_exists('records', $response)
|| ! is_array($response['records'])
) {
$this->logger->error('[RingCentral] Bad response', ['response' => $response]);
throw new RingCentralException('Bad response');
}
$extensions = $extensions->concat(
(new Collection($response['records']))
->transform([Extension::class, 'createFromPayload'])->toArray(),
);
if ($page === $response['paging']['totalPages']) {
break;
}
}
if ($page === self::EXTENSION_LIST_MAX_RETRIES) {
$this->logger->warning('[RingCentral] extension list max retries reached');
}
if ($extensions->isEmpty()) {
throw new RingCentralException('Could not retrieve extension list');
}
return $extensions;
}
public function getCallLog(array $payload, ?string $activityId = null): ?array
{
$endpoint = $activityId !== null
? sprintf('/restapi/v1.0/account/~/call-log/%s', $activityId)
: '/restapi/v1.0/account/~/call-log';
$limitKey = ThrottleHandler::getCallLogLimitKey($this->socialAccount);
$maxAttempts = (int) Cache::get($limitKey, 10);
$throttleKey = ThrottleHandler::getCallLogThrottleKey($this->socialAccount);
if ($this->rateLimiter->tooManyAttempts($throttleKey, $maxAttempts)) {
Datadog::increment('ringcentral.requests', 1, [
'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),
'status' => 'throttled',
'source' => 'client',
]);
$this->logger->info('[RingCentral] Rate limit exceeded', [
'throttle_key' => $throttleKey,
'attempts' => $this->rateLimiter->attempts($throttleKey),
'payload' => $payload,
]);
return null;
}
$this->rateLimiter->hit($throttleKey, self::RINGCENTRAL_HEAVY_REQUEST_LIMIT_WINDOW);
return $this->request('GET', $endpoint, $payload);
}
}
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
AiActivityType, folder
AiAutomation, folder
AiCallScoring, folder
AskAnything, folder
Dtos, folder
Events, folder
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi, folder
AWS, folder
BillingManagement, folder
Cache, folder
CoachingFeedback, folder
Country, folder
CustomerApi, folder
Database, folder
Datadog, folder
DateTime, folder
DealInsights, folder
DealRisks, folder
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection, folder
LiveFeed, folder
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
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
Exceptions, folder
Service, folder
BaseRateLimiter.php, class
EfficientJsonParser.php, class
ProviderRateLimiter.php, class
RateLimiterInstance.php, class
Uuid
Waveform
Webhooks
Workflow
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
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...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"37","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"35","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"63","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;","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.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"8","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Services\\Activity\\RingCentral;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Jiminny\\DTO\\ImportCall\\RingCentral\\Extension;\nuse Jiminny\\Exceptions\\ApiResponseException;\nuse Jiminny\\Exceptions\\HttpBadRequestException;\nuse Jiminny\\Exceptions\\HttpForbiddenException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Exceptions\\QuotaExceededException;\nuse Jiminny\\Exceptions\\RingCentralException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Services\\Activity\\ActivityProviderClient;\nuse League\\OAuth2\\Client\\Token\\AccessTokenInterface;\nuse Psr\\Http\\Message\\ResponseInterface;\nuse RingCentral\\SDK\\Http\\ApiException;\nuse RingCentral\\SDK\\Http\\ApiResponse;\nuse RingCentral\\SDK\\SDK;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass Client extends ActivityProviderClient\n{\n public const RINGCENTRAL_HEAVY_REQUEST_LIMIT_WINDOW = 60;\n private const ENDPOINT_EXTENSION_LIST = '/restapi/v1.0/account/~/extension';\n private const EXTENSION_LIST_MAX_RETRIES = 10;\n\n private RateLimiter $rateLimiter;\n\n public function __construct(?array $config)\n {\n parent::__construct($config);\n\n $this->rateLimiter = app(RateLimiter::class);\n }\n\n public function get(string $url, array $data = [])\n {\n return $this->requestWithAutomaticReauthorize('GET', $url, $data);\n }\n\n /**\n * Make a request to the endpoint.\n *\n * @param $method\n * @param $endpoint\n * @param array $options\n *\n * @throws ApiResponseException\n * @throws HttpBadRequestException\n * @throws HttpForbiddenException\n * @throws HttpNotFoundException\n * @throws QuotaExceededException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function request($method, $endpoint, array $options = [])\n {\n $this->checkExpiredToken();\n\n $client = $this->getSdk()->platform();\n $client->auth()->setData([\n 'access_token' => $this->accessToken,\n 'refresh_token' => $this->socialAccount->provider_refresh_token,\n 'expire_time' => $this->socialAccount->expires,\n 'expires_in' => $this->socialAccount->expires,\n 'token_type' => 'Bearer',\n 'refresh_token_expire_time' => $this->socialAccount->refresh_token_expires,\n ]);\n\n try {\n if (! $client->auth()->accessTokenValid()) {\n /** @var AccessTokenInterface $accessToken */\n $accessToken = $this->socialAccountService->refreshToken($this->socialAccount);\n // Due to the type definition of \"$this->accessToken\" as string,\n // the local class attribute will be cast to string via \"__toString\"\n $this->accessToken = $accessToken->getToken();\n\n $client->auth()->reset();\n $client->auth()->setData([\n 'access_token' => $accessToken->getToken(),\n 'refresh_token' => $accessToken->getRefreshToken(),\n 'expire_time' => $accessToken->getExpires(),\n 'token_type' => 'Bearer',\n ]);\n }\n } catch (Exception $ex) {\n Sentry::captureException($ex);\n $this->socialAccount->state = SocialAccount::STATE_FULL_REFRESH_REQUIRED;\n $this->socialAccount->save();\n\n throw new SocialAccountTokenInvalidException($ex->getMessage());\n }\n\n try {\n $headers = ['Authorization' => $this->getAuthHeader()];\n if ($method === 'POST') {\n $headers['Accept'] = 'application/json';\n $headers['Content-Type'] = 'application/json';\n\n /** @var ApiResponse $apiResponse */\n $apiResponse = $client->$method($endpoint, $options, [], $headers, []);\n\n return $apiResponse->jsonArray();\n }\n\n /** @var ApiResponse $apiResponse */\n $apiResponse = $client->$method($endpoint, $options, $headers, []);\n\n if (stripos($endpoint, '/call-log') !== false) {\n $limitKey = ThrottleHandler::getCallLogLimitKey($this->socialAccount);\n $this->setRateLimitFromHeader($apiResponse->response(), $limitKey);\n }\n\n Datadog::increment('ringcentral.requests', 1, [\n 'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),\n 'status' => 'success',\n 'source' => 'client',\n ]);\n\n // Response could be either null or containing at least data property.\n return $apiResponse->jsonArray();\n } catch (ApiException $apiException) {\n $errorCode = $apiException->getCode();\n $errorMessage = $apiException->getMessage();\n\n // Set social account state to full refresh\n if ($errorCode === Response::HTTP_FORBIDDEN) {\n $this->invalidateSocialAccount();\n }\n\n Sentry::captureException($apiException);\n\n Datadog::increment('ringcentral.requests', 1, [\n 'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),\n 'status' => Response::$statusTexts[$errorCode],\n 'source' => 'client',\n ]);\n\n throw new ApiResponseException($errorMessage, $errorCode, $apiException);\n } catch (Exception $e) {\n Sentry::captureException($e);\n\n throw new ApiResponseException($e->getMessage());\n }\n }\n\n private function invalidateSocialAccount(): void\n {\n $this->socialAccount->update(['state' => SocialAccount::STATE_FULL_REFRESH_REQUIRED]);\n }\n\n private function checkExpiredToken(): void\n {\n if ($this->socialAccount->refresh_token_expires < time()) {\n $this->invalidateSocialAccount();\n\n throw new SocialAccountTokenInvalidException('Token has expired');\n }\n }\n\n private function getSDK(): SDK\n {\n return new SDK(\n config('services.ringcentral.clientId'),\n config('services.ringcentral.clientSecret'),\n SDK::SERVER_PRODUCTION,\n );\n }\n\n // cache the rate limit header value for 1 day\n private function setRateLimitFromHeader(ResponseInterface $response, string $limitKey): void\n {\n if (Cache::has($limitKey)) {\n return;\n }\n\n try {\n $rateLimitHeader = $response->getHeader('X-Rate-Limit-Limit');\n $rateLimit = reset($rateLimitHeader);\n\n if (! empty($rateLimit)) {\n $rateLimit = (int) $rateLimit;\n Cache::put($limitKey, $rateLimit, now()->addHours(24));\n\n $this->logger->info('[RingCentral] Set Rate limit from header', [\n 'limit_key' => $limitKey,\n 'rate_limit' => $rateLimit,\n ]);\n } else {\n $this->logger->error('[RingCentral] Rate limit header not found', ['limit_key' => $limitKey]);\n }\n } catch (Throwable $exception) {\n $this->logger->error('[RingCentral] Get Rate limit header error', [\n 'limit_key' => $limitKey,\n 'exception' => $exception->getMessage(),\n ]);\n }\n }\n\n /**\n * @throws HttpNotFoundException\n * @throws \\JsonException\n * @throws QuotaExceededException\n * @throws HttpForbiddenException\n * @throws RingCentralException\n * @throws ServiceUnavailableException\n * @throws SocialAccountTokenInvalidException\n * @throws HttpBadRequestException\n */\n public function getCompanyExtensions(): Collection\n {\n $extensions = new Collection();\n\n $payload = [\n 'perPage' => 1000,\n 'page' => 1,\n 'type' => [Extension::TYPE_USER, Extension::TYPE_DEPARTMENT],\n ];\n\n for ($page = 1; $page <= self::EXTENSION_LIST_MAX_RETRIES; $page++) {\n $payload['page'] = $page;\n\n $response = $this->get(self::ENDPOINT_EXTENSION_LIST, $payload);\n\n if (\n ! is_array($response)\n || ! array_key_exists('records', $response)\n || ! is_array($response['records'])\n ) {\n $this->logger->error('[RingCentral] Bad response', ['response' => $response]);\n\n throw new RingCentralException('Bad response');\n }\n\n $extensions = $extensions->concat(\n (new Collection($response['records']))\n ->transform([Extension::class, 'createFromPayload'])->toArray(),\n );\n\n if ($page === $response['paging']['totalPages']) {\n break;\n }\n }\n\n if ($page === self::EXTENSION_LIST_MAX_RETRIES) {\n $this->logger->warning('[RingCentral] extension list max retries reached');\n }\n\n if ($extensions->isEmpty()) {\n throw new RingCentralException('Could not retrieve extension list');\n }\n\n return $extensions;\n }\n\n public function getCallLog(array $payload, ?string $activityId = null): ?array\n {\n $endpoint = $activityId !== null\n ? sprintf('/restapi/v1.0/account/~/call-log/%s', $activityId)\n : '/restapi/v1.0/account/~/call-log';\n\n $limitKey = ThrottleHandler::getCallLogLimitKey($this->socialAccount);\n $maxAttempts = (int) Cache::get($limitKey, 10);\n $throttleKey = ThrottleHandler::getCallLogThrottleKey($this->socialAccount);\n\n if ($this->rateLimiter->tooManyAttempts($throttleKey, $maxAttempts)) {\n Datadog::increment('ringcentral.requests', 1, [\n 'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),\n 'status' => 'throttled',\n 'source' => 'client',\n ]);\n\n $this->logger->info('[RingCentral] Rate limit exceeded', [\n 'throttle_key' => $throttleKey,\n 'attempts' => $this->rateLimiter->attempts($throttleKey),\n 'payload' => $payload,\n ]);\n\n return null;\n }\n\n $this->rateLimiter->hit($throttleKey, self::RINGCENTRAL_HEAVY_REQUEST_LIMIT_WINDOW);\n\n return $this->request('GET', $endpoint, $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Activity\\RingCentral;\n\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Jiminny\\DTO\\ImportCall\\RingCentral\\Extension;\nuse Jiminny\\Exceptions\\ApiResponseException;\nuse Jiminny\\Exceptions\\HttpBadRequestException;\nuse Jiminny\\Exceptions\\HttpForbiddenException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Exceptions\\QuotaExceededException;\nuse Jiminny\\Exceptions\\RingCentralException;\nuse Jiminny\\Exceptions\\ServiceUnavailableException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Services\\Activity\\ActivityProviderClient;\nuse League\\OAuth2\\Client\\Token\\AccessTokenInterface;\nuse Psr\\Http\\Message\\ResponseInterface;\nuse RingCentral\\SDK\\Http\\ApiException;\nuse RingCentral\\SDK\\Http\\ApiResponse;\nuse RingCentral\\SDK\\SDK;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass Client extends ActivityProviderClient\n{\n public const RINGCENTRAL_HEAVY_REQUEST_LIMIT_WINDOW = 60;\n private const ENDPOINT_EXTENSION_LIST = '/restapi/v1.0/account/~/extension';\n private const EXTENSION_LIST_MAX_RETRIES = 10;\n\n private RateLimiter $rateLimiter;\n\n public function __construct(?array $config)\n {\n parent::__construct($config);\n\n $this->rateLimiter = app(RateLimiter::class);\n }\n\n public function get(string $url, array $data = [])\n {\n return $this->requestWithAutomaticReauthorize('GET', $url, $data);\n }\n\n /**\n * Make a request to the endpoint.\n *\n * @param $method\n * @param $endpoint\n * @param array $options\n *\n * @throws ApiResponseException\n * @throws HttpBadRequestException\n * @throws HttpForbiddenException\n * @throws HttpNotFoundException\n * @throws QuotaExceededException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function request($method, $endpoint, array $options = [])\n {\n $this->checkExpiredToken();\n\n $client = $this->getSdk()->platform();\n $client->auth()->setData([\n 'access_token' => $this->accessToken,\n 'refresh_token' => $this->socialAccount->provider_refresh_token,\n 'expire_time' => $this->socialAccount->expires,\n 'expires_in' => $this->socialAccount->expires,\n 'token_type' => 'Bearer',\n 'refresh_token_expire_time' => $this->socialAccount->refresh_token_expires,\n ]);\n\n try {\n if (! $client->auth()->accessTokenValid()) {\n /** @var AccessTokenInterface $accessToken */\n $accessToken = $this->socialAccountService->refreshToken($this->socialAccount);\n // Due to the type definition of \"$this->accessToken\" as string,\n // the local class attribute will be cast to string via \"__toString\"\n $this->accessToken = $accessToken->getToken();\n\n $client->auth()->reset();\n $client->auth()->setData([\n 'access_token' => $accessToken->getToken(),\n 'refresh_token' => $accessToken->getRefreshToken(),\n 'expire_time' => $accessToken->getExpires(),\n 'token_type' => 'Bearer',\n ]);\n }\n } catch (Exception $ex) {\n Sentry::captureException($ex);\n $this->socialAccount->state = SocialAccount::STATE_FULL_REFRESH_REQUIRED;\n $this->socialAccount->save();\n\n throw new SocialAccountTokenInvalidException($ex->getMessage());\n }\n\n try {\n $headers = ['Authorization' => $this->getAuthHeader()];\n if ($method === 'POST') {\n $headers['Accept'] = 'application/json';\n $headers['Content-Type'] = 'application/json';\n\n /** @var ApiResponse $apiResponse */\n $apiResponse = $client->$method($endpoint, $options, [], $headers, []);\n\n return $apiResponse->jsonArray();\n }\n\n /** @var ApiResponse $apiResponse */\n $apiResponse = $client->$method($endpoint, $options, $headers, []);\n\n if (stripos($endpoint, '/call-log') !== false) {\n $limitKey = ThrottleHandler::getCallLogLimitKey($this->socialAccount);\n $this->setRateLimitFromHeader($apiResponse->response(), $limitKey);\n }\n\n Datadog::increment('ringcentral.requests', 1, [\n 'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),\n 'status' => 'success',\n 'source' => 'client',\n ]);\n\n // Response could be either null or containing at least data property.\n return $apiResponse->jsonArray();\n } catch (ApiException $apiException) {\n $errorCode = $apiException->getCode();\n $errorMessage = $apiException->getMessage();\n\n // Set social account state to full refresh\n if ($errorCode === Response::HTTP_FORBIDDEN) {\n $this->invalidateSocialAccount();\n }\n\n Sentry::captureException($apiException);\n\n Datadog::increment('ringcentral.requests', 1, [\n 'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),\n 'status' => Response::$statusTexts[$errorCode],\n 'source' => 'client',\n ]);\n\n throw new ApiResponseException($errorMessage, $errorCode, $apiException);\n } catch (Exception $e) {\n Sentry::captureException($e);\n\n throw new ApiResponseException($e->getMessage());\n }\n }\n\n private function invalidateSocialAccount(): void\n {\n $this->socialAccount->update(['state' => SocialAccount::STATE_FULL_REFRESH_REQUIRED]);\n }\n\n private function checkExpiredToken(): void\n {\n if ($this->socialAccount->refresh_token_expires < time()) {\n $this->invalidateSocialAccount();\n\n throw new SocialAccountTokenInvalidException('Token has expired');\n }\n }\n\n private function getSDK(): SDK\n {\n return new SDK(\n config('services.ringcentral.clientId'),\n config('services.ringcentral.clientSecret'),\n SDK::SERVER_PRODUCTION,\n );\n }\n\n // cache the rate limit header value for 1 day\n private function setRateLimitFromHeader(ResponseInterface $response, string $limitKey): void\n {\n if (Cache::has($limitKey)) {\n return;\n }\n\n try {\n $rateLimitHeader = $response->getHeader('X-Rate-Limit-Limit');\n $rateLimit = reset($rateLimitHeader);\n\n if (! empty($rateLimit)) {\n $rateLimit = (int) $rateLimit;\n Cache::put($limitKey, $rateLimit, now()->addHours(24));\n\n $this->logger->info('[RingCentral] Set Rate limit from header', [\n 'limit_key' => $limitKey,\n 'rate_limit' => $rateLimit,\n ]);\n } else {\n $this->logger->error('[RingCentral] Rate limit header not found', ['limit_key' => $limitKey]);\n }\n } catch (Throwable $exception) {\n $this->logger->error('[RingCentral] Get Rate limit header error', [\n 'limit_key' => $limitKey,\n 'exception' => $exception->getMessage(),\n ]);\n }\n }\n\n /**\n * @throws HttpNotFoundException\n * @throws \\JsonException\n * @throws QuotaExceededException\n * @throws HttpForbiddenException\n * @throws RingCentralException\n * @throws ServiceUnavailableException\n * @throws SocialAccountTokenInvalidException\n * @throws HttpBadRequestException\n */\n public function getCompanyExtensions(): Collection\n {\n $extensions = new Collection();\n\n $payload = [\n 'perPage' => 1000,\n 'page' => 1,\n 'type' => [Extension::TYPE_USER, Extension::TYPE_DEPARTMENT],\n ];\n\n for ($page = 1; $page <= self::EXTENSION_LIST_MAX_RETRIES; $page++) {\n $payload['page'] = $page;\n\n $response = $this->get(self::ENDPOINT_EXTENSION_LIST, $payload);\n\n if (\n ! is_array($response)\n || ! array_key_exists('records', $response)\n || ! is_array($response['records'])\n ) {\n $this->logger->error('[RingCentral] Bad response', ['response' => $response]);\n\n throw new RingCentralException('Bad response');\n }\n\n $extensions = $extensions->concat(\n (new Collection($response['records']))\n ->transform([Extension::class, 'createFromPayload'])->toArray(),\n );\n\n if ($page === $response['paging']['totalPages']) {\n break;\n }\n }\n\n if ($page === self::EXTENSION_LIST_MAX_RETRIES) {\n $this->logger->warning('[RingCentral] extension list max retries reached');\n }\n\n if ($extensions->isEmpty()) {\n throw new RingCentralException('Could not retrieve extension list');\n }\n\n return $extensions;\n }\n\n public function getCallLog(array $payload, ?string $activityId = null): ?array\n {\n $endpoint = $activityId !== null\n ? sprintf('/restapi/v1.0/account/~/call-log/%s', $activityId)\n : '/restapi/v1.0/account/~/call-log';\n\n $limitKey = ThrottleHandler::getCallLogLimitKey($this->socialAccount);\n $maxAttempts = (int) Cache::get($limitKey, 10);\n $throttleKey = ThrottleHandler::getCallLogThrottleKey($this->socialAccount);\n\n if ($this->rateLimiter->tooManyAttempts($throttleKey, $maxAttempts)) {\n Datadog::increment('ringcentral.requests', 1, [\n 'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),\n 'status' => 'throttled',\n 'source' => 'client',\n ]);\n\n $this->logger->info('[RingCentral] Rate limit exceeded', [\n 'throttle_key' => $throttleKey,\n 'attempts' => $this->rateLimiter->attempts($throttleKey),\n 'payload' => $payload,\n ]);\n\n return null;\n }\n\n $this->rateLimiter->hit($throttleKey, self::RINGCENTRAL_HEAVY_REQUEST_LIMIT_WINDOW);\n\n return $this->request('GET', $endpoint, $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Exceptions, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Service, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BaseRateLimiter.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EfficientJsonParser.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProviderRateLimiter.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimiterInstance.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"on_screen":false,"role_description":"text"}]...
|
-9074887548874651521
|
2218617733067978317
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Code changed:
Hide
Sync Changes
Hide This Notification
37
1
35
63
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
Sync Changes
Hide This Notification
Code changed:
Hide
8
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Activity\RingCentral;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Cache\RateLimiter;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Jiminny\DTO\ImportCall\RingCentral\Extension;
use Jiminny\Exceptions\ApiResponseException;
use Jiminny\Exceptions\HttpBadRequestException;
use Jiminny\Exceptions\HttpForbiddenException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Exceptions\QuotaExceededException;
use Jiminny\Exceptions\RingCentralException;
use Jiminny\Exceptions\ServiceUnavailableException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\SocialAccount;
use Jiminny\Services\Activity\ActivityProviderClient;
use League\OAuth2\Client\Token\AccessTokenInterface;
use Psr\Http\Message\ResponseInterface;
use RingCentral\SDK\Http\ApiException;
use RingCentral\SDK\Http\ApiResponse;
use RingCentral\SDK\SDK;
use Sentry;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class Client extends ActivityProviderClient
{
public const RINGCENTRAL_HEAVY_REQUEST_LIMIT_WINDOW = 60;
private const ENDPOINT_EXTENSION_LIST = '/restapi/v1.0/account/~/extension';
private const EXTENSION_LIST_MAX_RETRIES = 10;
private RateLimiter $rateLimiter;
public function __construct(?array $config)
{
parent::__construct($config);
$this->rateLimiter = app(RateLimiter::class);
}
public function get(string $url, array $data = [])
{
return $this->requestWithAutomaticReauthorize('GET', $url, $data);
}
/**
* Make a request to the endpoint.
*
* @param $method
* @param $endpoint
* @param array $options
*
* @throws ApiResponseException
* @throws HttpBadRequestException
* @throws HttpForbiddenException
* @throws HttpNotFoundException
* @throws QuotaExceededException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function request($method, $endpoint, array $options = [])
{
$this->checkExpiredToken();
$client = $this->getSdk()->platform();
$client->auth()->setData([
'access_token' => $this->accessToken,
'refresh_token' => $this->socialAccount->provider_refresh_token,
'expire_time' => $this->socialAccount->expires,
'expires_in' => $this->socialAccount->expires,
'token_type' => 'Bearer',
'refresh_token_expire_time' => $this->socialAccount->refresh_token_expires,
]);
try {
if (! $client->auth()->accessTokenValid()) {
/** @var AccessTokenInterface $accessToken */
$accessToken = $this->socialAccountService->refreshToken($this->socialAccount);
// Due to the type definition of "$this->accessToken" as string,
// the local class attribute will be cast to string via "__toString"
$this->accessToken = $accessToken->getToken();
$client->auth()->reset();
$client->auth()->setData([
'access_token' => $accessToken->getToken(),
'refresh_token' => $accessToken->getRefreshToken(),
'expire_time' => $accessToken->getExpires(),
'token_type' => 'Bearer',
]);
}
} catch (Exception $ex) {
Sentry::captureException($ex);
$this->socialAccount->state = SocialAccount::STATE_FULL_REFRESH_REQUIRED;
$this->socialAccount->save();
throw new SocialAccountTokenInvalidException($ex->getMessage());
}
try {
$headers = ['Authorization' => $this->getAuthHeader()];
if ($method === 'POST') {
$headers['Accept'] = 'application/json';
$headers['Content-Type'] = 'application/json';
/** @var ApiResponse $apiResponse */
$apiResponse = $client->$method($endpoint, $options, [], $headers, []);
return $apiResponse->jsonArray();
}
/** @var ApiResponse $apiResponse */
$apiResponse = $client->$method($endpoint, $options, $headers, []);
if (stripos($endpoint, '/call-log') !== false) {
$limitKey = ThrottleHandler::getCallLogLimitKey($this->socialAccount);
$this->setRateLimitFromHeader($apiResponse->response(), $limitKey);
}
Datadog::increment('ringcentral.requests', 1, [
'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),
'status' => 'success',
'source' => 'client',
]);
// Response could be either null or containing at least data property.
return $apiResponse->jsonArray();
} catch (ApiException $apiException) {
$errorCode = $apiException->getCode();
$errorMessage = $apiException->getMessage();
// Set social account state to full refresh
if ($errorCode === Response::HTTP_FORBIDDEN) {
$this->invalidateSocialAccount();
}
Sentry::captureException($apiException);
Datadog::increment('ringcentral.requests', 1, [
'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),
'status' => Response::$statusTexts[$errorCode],
'source' => 'client',
]);
throw new ApiResponseException($errorMessage, $errorCode, $apiException);
} catch (Exception $e) {
Sentry::captureException($e);
throw new ApiResponseException($e->getMessage());
}
}
private function invalidateSocialAccount(): void
{
$this->socialAccount->update(['state' => SocialAccount::STATE_FULL_REFRESH_REQUIRED]);
}
private function checkExpiredToken(): void
{
if ($this->socialAccount->refresh_token_expires < time()) {
$this->invalidateSocialAccount();
throw new SocialAccountTokenInvalidException('Token has expired');
}
}
private function getSDK(): SDK
{
return new SDK(
config('services.ringcentral.clientId'),
config('services.ringcentral.clientSecret'),
SDK::SERVER_PRODUCTION,
);
}
// cache the rate limit header value for 1 day
private function setRateLimitFromHeader(ResponseInterface $response, string $limitKey): void
{
if (Cache::has($limitKey)) {
return;
}
try {
$rateLimitHeader = $response->getHeader('X-Rate-Limit-Limit');
$rateLimit = reset($rateLimitHeader);
if (! empty($rateLimit)) {
$rateLimit = (int) $rateLimit;
Cache::put($limitKey, $rateLimit, now()->addHours(24));
$this->logger->info('[RingCentral] Set Rate limit from header', [
'limit_key' => $limitKey,
'rate_limit' => $rateLimit,
]);
} else {
$this->logger->error('[RingCentral] Rate limit header not found', ['limit_key' => $limitKey]);
}
} catch (Throwable $exception) {
$this->logger->error('[RingCentral] Get Rate limit header error', [
'limit_key' => $limitKey,
'exception' => $exception->getMessage(),
]);
}
}
/**
* @throws HttpNotFoundException
* @throws \JsonException
* @throws QuotaExceededException
* @throws HttpForbiddenException
* @throws RingCentralException
* @throws ServiceUnavailableException
* @throws SocialAccountTokenInvalidException
* @throws HttpBadRequestException
*/
public function getCompanyExtensions(): Collection
{
$extensions = new Collection();
$payload = [
'perPage' => 1000,
'page' => 1,
'type' => [Extension::TYPE_USER, Extension::TYPE_DEPARTMENT],
];
for ($page = 1; $page <= self::EXTENSION_LIST_MAX_RETRIES; $page++) {
$payload['page'] = $page;
$response = $this->get(self::ENDPOINT_EXTENSION_LIST, $payload);
if (
! is_array($response)
|| ! array_key_exists('records', $response)
|| ! is_array($response['records'])
) {
$this->logger->error('[RingCentral] Bad response', ['response' => $response]);
throw new RingCentralException('Bad response');
}
$extensions = $extensions->concat(
(new Collection($response['records']))
->transform([Extension::class, 'createFromPayload'])->toArray(),
);
if ($page === $response['paging']['totalPages']) {
break;
}
}
if ($page === self::EXTENSION_LIST_MAX_RETRIES) {
$this->logger->warning('[RingCentral] extension list max retries reached');
}
if ($extensions->isEmpty()) {
throw new RingCentralException('Could not retrieve extension list');
}
return $extensions;
}
public function getCallLog(array $payload, ?string $activityId = null): ?array
{
$endpoint = $activityId !== null
? sprintf('/restapi/v1.0/account/~/call-log/%s', $activityId)
: '/restapi/v1.0/account/~/call-log';
$limitKey = ThrottleHandler::getCallLogLimitKey($this->socialAccount);
$maxAttempts = (int) Cache::get($limitKey, 10);
$throttleKey = ThrottleHandler::getCallLogThrottleKey($this->socialAccount);
if ($this->rateLimiter->tooManyAttempts($throttleKey, $maxAttempts)) {
Datadog::increment('ringcentral.requests', 1, [
'team' => $this->socialAccount->getUser()->getTeam()->getSlug(),
'status' => 'throttled',
'source' => 'client',
]);
$this->logger->info('[RingCentral] Rate limit exceeded', [
'throttle_key' => $throttleKey,
'attempts' => $this->rateLimiter->attempts($throttleKey),
'payload' => $payload,
]);
return null;
}
$this->rateLimiter->hit($throttleKey, self::RINGCENTRAL_HEAVY_REQUEST_LIMIT_WINDOW);
return $this->request('GET', $endpoint, $payload);
}
}
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
AiActivityType, folder
AiAutomation, folder
AiCallScoring, folder
AskAnything, folder
Dtos, folder
Events, folder
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi, folder
AWS, folder
BillingManagement, folder
Cache, folder
CoachingFeedback, folder
Country, folder
CustomerApi, folder
Database, folder
Datadog, folder
DateTime, folder
DealInsights, folder
DealRisks, folder
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection, folder
LiveFeed, folder
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
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
Exceptions, folder
Service, folder
BaseRateLimiter.php, class
EfficientJsonParser.php, class
ProviderRateLimiter.php, class
RateLimiterInstance.php, class
Uuid
Waveform
Webhooks
Workflow
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
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...
|
1032
|
NULL
|
NULL
|
NULL
|
|
18794
|
807
|
15
|
2026-05-11T11:48:18.163681+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778500098163_m2.jpg...
|
Firefox
|
Personal — Mozilla Firefox
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Screenpipe — Archive
app.screenpipe.lakylak.xyz
Ne Screenpipe — Archive
app.screenpipe.lakylak.xyz
New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
Close tab
New Tab
New Tab
Close tab
New Tab...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Screenpipe — Archive","depth":4,"bounds":{"left":0.4119016,"top":0.11412609,"width":0.03956117,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.screenpipe.lakylak.xyz","depth":4,"bounds":{"left":0.4119016,"top":0.12490024,"width":0.047041222,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.2942154,"top":0.074221864,"width":0.113696806,"height":0.032721467},"on_screen":true,"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.3075133,"top":0.08539505,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"bounds":{"left":0.2942154,"top":0.10694334,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"bounds":{"left":0.3075133,"top":0.11811652,"width":0.037898935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.3956117,"top":0.11412609,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.2942154,"top":0.1396648,"width":0.113696806,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.3075133,"top":0.15083799,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.3956117,"top":0.14684756,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.29704124,"top":0.17398244,"width":0.108211435,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-9074264645788080590
|
2685712508440140689
|
visual_change
|
accessibility
|
NULL
|
Screenpipe — Archive
app.screenpipe.lakylak.xyz
Ne Screenpipe — Archive
app.screenpipe.lakylak.xyz
New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
Close tab
New Tab
New Tab
Close tab
New Tab...
|
18793
|
NULL
|
NULL
|
NULL
|
|
17450
|
772
|
20
|
2026-05-11T10:23:37.663179+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778495017663_m1.jpg...
|
Firefox
|
Screenpipe — Archive — Personal
|
True
|
app.screenpipe.lakylak.xyz
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
New Tab
New Tab
Screenpipe — Archive
Screenpipe — New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe [archive.db · 12323.6MB]
Screenpipe
[archive.db · 12323.6MB]
Activity
Search
Audio
Work Report
Timetable
AI Summary
Date
07
/
05
/
2026
Calendar
SECONDLY
Search
AND also
second required term — both must appear in same result (optional)
Source
App
Date
dd
/
mm
/
yyyy
Calendar
(blank = all dates)
From
--
:
--
To
--
:
--
Only apps
any app (blank = all)
▾
Skip apps
none skipped...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"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.043402776,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.06631944,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.08958333,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"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.112847224,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.13611111,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe [archive.db · 12323.6MB]","depth":7,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[archive.db · 12323.6MB]","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"on_screen":true,"help_text":"No audio data in this database","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Timetable","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"07","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"05","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"SECONDLY","depth":8,"on_screen":true,"value":"SECONDLY","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"AND also","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"second required term — both must appear in same result (optional)","depth":8,"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Source","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"App","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dd","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mm","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"yyyy","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"(blank = all dates)","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"From","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"To","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Only apps","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"any app (blank = all)","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"▾","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skip apps","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"none skipped","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9073122621874147303
|
-5309684545353566317
|
click
|
accessibility
|
NULL
|
New Tab
New Tab
Screenpipe — Archive
Screenpipe — New Tab
New Tab
Screenpipe — Archive
Screenpipe — Archive
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe [archive.db · 12323.6MB]
Screenpipe
[archive.db · 12323.6MB]
Activity
Search
Audio
Work Report
Timetable
AI Summary
Date
07
/
05
/
2026
Calendar
SECONDLY
Search
AND also
second required term — both must appear in same result (optional)
Source
App
Date
dd
/
mm
/
yyyy
Calendar
(blank = all dates)
From
--
:
--
To
--
:
--
Only apps
any app (blank = all)
▾
Skip apps
none skipped...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
10399
|
472
|
36
|
2026-05-08T17:21:34.861234+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-08/1778 /Users/lukas/.screenpipe/data/data/2026-05-08/1778260894861_m2.jpg...
|
Code
|
1. Message that arrives … — payments-logger [SSH: 1. Message that arrives … — payments-logger [SSH: nas]...
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: payments-logger [SSH: nas]
Explorer Section: payments-logger [SSH: nas]
PAYMENTS-LOGGER [SSH: NAS]
.claude
backend
prisma
migrations
schema.prisma
src
routes
auth.js
index.js
parser.js
.dockerignore
Dockerfile
package.json
frontend
.env
.env.example
.gitignore
API.md
docker-compose.yml
README.md
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
README.md, Editor Group 1
index.js, preview, Editor Group 1
index.js, preview, Editor Group 1
1. Message that arrives …, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: nas
SSH: nas
No Problems
0
0
No Ports Forwarded
0
Analyzing 'index.js' and its dependencies
Analyzing 'index.js' and its dependencies
Notifications
Signed out
Signed out
Screen Reader Optimized
Info: Setting up SSH Host nas: Setting up SSH tunnel
Yes
No
Learn More
Screen reader usage detected. Do you want to enable editor.accessibilitySupport to optimize the editor for screen reader usage?...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Explorer (⇧⌘E)","depth":19,"bounds":{"left":0.0,"top":0.047885075,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":true},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.057462092,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Search (⇧⌘F)","depth":19,"bounds":{"left":0.0,"top":0.08619314,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.09577015,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Source Control (⌃⇧G)","depth":19,"bounds":{"left":0.0,"top":0.1245012,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.13407822,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Run and Debug (⇧⌘D)","depth":19,"bounds":{"left":0.0,"top":0.16280925,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.17238627,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Remote Explorer","depth":19,"bounds":{"left":0.0,"top":0.20111732,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.21069433,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Extensions (⇧⌘X) - 2 require update","depth":19,"bounds":{"left":0.0,"top":0.23942538,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":22,"bounds":{"left":0.0039893617,"top":0.2490024,"width":0.007978723,"height":0.01915403},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":22,"bounds":{"left":0.009640957,"top":0.2601756,"width":0.0019946808,"height":0.008778931},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Claude Code","depth":19,"bounds":{"left":0.0,"top":0.27773345,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Containers","depth":19,"bounds":{"left":0.0,"top":0.3160415,"width":0.015957447,"height":0.03830806},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"EXPLORER","depth":17,"bounds":{"left":0.022606382,"top":0.047885075,"width":0.018949468,"height":0.02793296},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"EXPLORER","depth":18,"bounds":{"left":0.022606382,"top":0.056664005,"width":0.018949468,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.022606382,"top":0.056664005,"width":0.0023271276,"height":0.0103751}},{"char_start":1,"char_count":7,"bounds":{"left":0.024933511,"top":0.056664005,"width":0.01662234,"height":0.0103751}}],"role_description":"text"},{"role":"AXButton","text":"Explorer Section: payments-logger [SSH: nas]","depth":21,"bounds":{"left":0.015957447,"top":0.07581804,"width":0.09940159,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"","depth":23,"bounds":{"left":0.01662234,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"Explorer Section: payments-logger [SSH: nas]","depth":22,"bounds":{"left":0.022606382,"top":0.07581804,"width":0.06017287,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"PAYMENTS-LOGGER [SSH: NAS]","depth":23,"bounds":{"left":0.022606382,"top":0.079010375,"width":0.06017287,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.022606382,"top":0.07980846,"width":0.0023271276,"height":0.0103751}},{"char_start":1,"char_count":25,"bounds":{"left":0.024933511,"top":0.07980846,"width":0.05817819,"height":0.0103751}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.019614361,"top":0.09577015,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".claude","depth":27,"bounds":{"left":0.025930852,"top":0.09577015,"width":0.01462766,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.096568234,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.027260639,"top":0.096568234,"width":0.013297873,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.019614361,"top":0.11332801,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":27,"bounds":{"left":0.025930852,"top":0.11332801,"width":0.017287234,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.11412609,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.028590426,"top":0.11412609,"width":0.01462766,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.13088587,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"prisma","depth":27,"bounds":{"left":0.028590426,"top":0.13088587,"width":0.013630319,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.13168396,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":5,"bounds":{"left":0.03125,"top":0.13168396,"width":0.010970744,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.14844373,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"migrations","depth":27,"bounds":{"left":0.03125,"top":0.14844373,"width":0.021276595,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.14924182,"width":0.003656915,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.034906916,"top":0.14924182,"width":0.01761968,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.16440542,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"schema.prisma","depth":27,"bounds":{"left":0.03125,"top":0.1660016,"width":0.030585106,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.16679968,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":12,"bounds":{"left":0.03357713,"top":0.16679968,"width":0.02825798,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.022273935,"top":0.18355946,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"src","depth":27,"bounds":{"left":0.028590426,"top":0.18355946,"width":0.0063164895,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.18435754,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":2,"bounds":{"left":0.030917553,"top":0.18435754,"width":0.0039893617,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.024933511,"top":0.20111732,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"routes","depth":27,"bounds":{"left":0.03125,"top":0.20111732,"width":0.012632979,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.2019154,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":5,"bounds":{"left":0.032912236,"top":0.2019154,"width":0.011303191,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.21707901,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"auth.js","depth":27,"bounds":{"left":0.03125,"top":0.21867518,"width":0.013297873,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.21947326,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.03357713,"top":0.21947326,"width":0.011303191,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.23463687,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"index.js","depth":27,"bounds":{"left":0.03125,"top":0.23623304,"width":0.015292553,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.23703113,"width":0.0009973404,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.032247342,"top":0.23703113,"width":0.014295213,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.023936171,"top":0.25219473,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"parser.js","depth":27,"bounds":{"left":0.03125,"top":0.25379092,"width":0.016954787,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.03125,"top":0.254589,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":8,"bounds":{"left":0.033909574,"top":0.254589,"width":0.01462766,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.2697526,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".dockerignore","depth":27,"bounds":{"left":0.028590426,"top":0.27134877,"width":0.027593086,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.27214685,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":12,"bounds":{"left":0.029920213,"top":0.27214685,"width":0.026595745,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.28731045,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Dockerfile","depth":27,"bounds":{"left":0.028590426,"top":0.28890663,"width":0.020611702,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.2897047,"width":0.0033244682,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.031914894,"top":0.2897047,"width":0.017287234,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.021276595,"top":0.3048683,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"package.json","depth":27,"bounds":{"left":0.028590426,"top":0.3064645,"width":0.026595745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.028590426,"top":0.30726257,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":11,"bounds":{"left":0.03125,"top":0.30726257,"width":0.023936171,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":26,"bounds":{"left":0.019614361,"top":0.32402235,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"frontend","depth":27,"bounds":{"left":0.025930852,"top":0.32402235,"width":0.017287234,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.32482043,"width":0.0016622341,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.027593086,"top":0.32482043,"width":0.015625,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.01861702,"top":0.33998403,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env","depth":27,"bounds":{"left":0.025930852,"top":0.3415802,"width":0.00831117,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.3423783,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.027260639,"top":0.3423783,"width":0.006981383,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.01861702,"top":0.3575419,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".env.example","depth":27,"bounds":{"left":0.025930852,"top":0.35913807,"width":0.025930852,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.35993615,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":11,"bounds":{"left":0.027260639,"top":0.35993615,"width":0.024933511,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.01861702,"top":0.37509975,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".gitignore","depth":27,"bounds":{"left":0.025930852,"top":0.37669593,"width":0.018949468,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.377494,"width":0.0013297872,"height":0.011971269}},{"char_start":1,"char_count":9,"bounds":{"left":0.027260639,"top":0.377494,"width":0.017952127,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.01861702,"top":0.3926576,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"API.md","depth":27,"bounds":{"left":0.025930852,"top":0.3942538,"width":0.014295213,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.39505187,"width":0.0029920214,"height":0.011971269}},{"char_start":1,"char_count":5,"bounds":{"left":0.028922873,"top":0.39505187,"width":0.011303191,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.01861702,"top":0.4102155,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"docker-compose.yml","depth":27,"bounds":{"left":0.025930852,"top":0.41181165,"width":0.042220745,"height":0.011971269},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.025930852,"top":0.41260973,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":17,"bounds":{"left":0.028590426,"top":0.41260973,"width":0.03956117,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"","depth":27,"bounds":{"left":0.01861702,"top":0.42777336,"width":0.0063164895,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"README.md","depth":27,"bounds":{"left":0.025930852,"top":0.4293695,"width":0.025265958,"height":0.011971269},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Outline Section","depth":21,"bounds":{"left":0.015957447,"top":0.9473264,"width":0.09940159,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":23,"bounds":{"left":0.01662234,"top":0.9497207,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"OUTLINE","depth":22,"bounds":{"left":0.022606382,"top":0.9473264,"width":0.01662234,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"OUTLINE","depth":23,"bounds":{"left":0.022606382,"top":0.95131683,"width":0.01662234,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.022606382,"top":0.95131683,"width":0.0029920214,"height":0.0103751}},{"char_start":1,"char_count":6,"bounds":{"left":0.025598405,"top":0.95131683,"width":0.013630319,"height":0.0103751}}],"role_description":"text"},{"role":"AXButton","text":"Timeline Section","depth":21,"bounds":{"left":0.015957447,"top":0.9648843,"width":0.09940159,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":23,"bounds":{"left":0.01662234,"top":0.96727854,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXHeading","text":"TIMELINE","depth":22,"bounds":{"left":0.022606382,"top":0.9648843,"width":0.01761968,"height":0.017557861},"on_screen":true,"role_description":"heading"},{"role":"AXStaticText","text":"TIMELINE","depth":23,"bounds":{"left":0.022606382,"top":0.9688747,"width":0.01761968,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.022606382,"top":0.9688747,"width":0.0026595744,"height":0.0103751}},{"char_start":1,"char_count":7,"bounds":{"left":0.025265958,"top":0.9688747,"width":0.015292553,"height":0.0103751}}],"role_description":"text"},{"role":"AXRadioButton","text":"README.md, Editor Group 1","depth":28,"bounds":{"left":0.11569149,"top":0.047885075,"width":0.045545213,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"index.js, preview, Editor Group 1","depth":28,"bounds":{"left":0.1612367,"top":0.047885075,"width":0.039893616,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.13796543,"top":0.07821229,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":29,"bounds":{"left":0.14960106,"top":0.07821229,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"index.js, preview, Editor Group 1","depth":28,"bounds":{"left":0.11569149,"top":0.0933759,"width":0.38031915,"height":0.0007980846},"on_screen":true,"role_description":"editor","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"1. Message that arrives …, Editor Group 2","depth":28,"bounds":{"left":0.5578458,"top":0.047885075,"width":0.071476065,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXRadioButton","text":"Problems (⇧⌘M)","depth":22,"bounds":{"left":0.118351065,"top":0.64644855,"width":0.027925532,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PROBLEMS","depth":24,"bounds":{"left":0.122340426,"top":0.6552275,"width":0.019946808,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Output (⇧⌘U)","depth":22,"bounds":{"left":0.14594415,"top":0.64644855,"width":0.023603724,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"OUTPUT","depth":24,"bounds":{"left":0.14993352,"top":0.6552275,"width":0.015625,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Debug Console (⇧⌘Y)","depth":22,"bounds":{"left":0.16921543,"top":0.64644855,"width":0.039893616,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DEBUG CONSOLE","depth":24,"bounds":{"left":0.1732048,"top":0.6552275,"width":0.031914894,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Terminal (⌃`)","depth":22,"bounds":{"left":0.2087766,"top":0.64644855,"width":0.026595745,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":true},{"role":"AXStaticText","text":"TERMINAL","depth":24,"bounds":{"left":0.21276596,"top":0.6552275,"width":0.01861702,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.2130984,"top":0.6560255,"width":0.0023271276,"height":0.0103751}},{"char_start":1,"char_count":7,"bounds":{"left":0.21542554,"top":0.6560255,"width":0.016289894,"height":0.0103751}}],"role_description":"text"},{"role":"AXRadioButton","text":"Ports","depth":22,"bounds":{"left":0.23537233,"top":0.64644855,"width":0.020279255,"height":0.02793296},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PORTS","depth":24,"bounds":{"left":0.2393617,"top":0.6552275,"width":0.012300532,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"remote SSH: nas","depth":16,"bounds":{"left":0.0006648936,"top":0.98244214,"width":0.028590426,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.0033244682,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SSH: nas","depth":17,"bounds":{"left":0.008643617,"top":0.9856345,"width":0.017952127,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.008643617,"top":0.9856345,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.009973404,"top":0.9856345,"width":0.01462766,"height":0.011173184}}],"role_description":"text"},{"role":"AXButton","text":"No Problems","depth":16,"bounds":{"left":0.03025266,"top":0.98244214,"width":0.022606382,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.031914894,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.03723404,"top":0.9856345,"width":0.004986702,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.041888297,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.04720745,"top":0.9856345,"width":0.0039893617,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"No Ports Forwarded","depth":16,"bounds":{"left":0.054521278,"top":0.98244214,"width":0.012632979,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.05618351,"top":0.9848364,"width":0.0056515955,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"0","depth":17,"bounds":{"left":0.061502658,"top":0.9856345,"width":0.0039893617,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Analyzing 'index.js' and its dependencies","depth":16,"bounds":{"left":0.06881649,"top":0.98244214,"width":0.08743351,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.06948138,"top":0.98244214,"width":0.0076462766,"height":0.01755786},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Analyzing 'index.js' and its dependencies","depth":17,"bounds":{"left":0.07579787,"top":0.9856345,"width":0.0787899,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.076130316,"top":0.9856345,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":40,"bounds":{"left":0.07712766,"top":0.9856345,"width":0.075465426,"height":0.011173184}}],"role_description":"text"},{"role":"AXButton","text":"Notifications","depth":16,"bounds":{"left":0.9886968,"top":0.98244214,"width":0.010638298,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Signed out","depth":16,"bounds":{"left":0.9567819,"top":0.98244214,"width":0.031914894,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":17,"bounds":{"left":0.9594415,"top":0.9848364,"width":0.005319149,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Signed out","depth":17,"bounds":{"left":0.96476066,"top":0.9856345,"width":0.021276595,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.96476066,"top":0.9856345,"width":0.0013297872,"height":0.011173184}},{"char_start":1,"char_count":9,"bounds":{"left":0.96575797,"top":0.9856345,"width":0.018949468,"height":0.011173184}}],"role_description":"text"},{"role":"AXButton","text":"Screen Reader Optimized","depth":16,"bounds":{"left":0.90359044,"top":0.98244214,"width":0.05319149,"height":0.01755786},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Info: Setting up SSH Host nas: Setting up SSH tunnel","depth":12,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Yes","depth":15,"bounds":{"left":0.9361702,"top":0.94413406,"width":0.012965426,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"No","depth":15,"bounds":{"left":0.95212764,"top":0.94413406,"width":0.011635638,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Learn More","depth":15,"bounds":{"left":0.96675533,"top":0.94413406,"width":0.027260639,"height":0.0207502},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":16,"bounds":{"left":0.8507314,"top":0.88347965,"width":0.005984043,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Screen reader usage detected. Do you want to enable editor.accessibilitySupport to optimize the editor for screen reader usage?","depth":16,"bounds":{"left":0.8580452,"top":0.88427776,"width":0.11968085,"height":0.04708699},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.8580452,"top":0.8850758,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":126,"bounds":{"left":0.8580452,"top":0.8850758,"width":0.11968085,"height":0.04708699}}],"role_description":"text"}]...
|
-9073111615613911620
|
-6825039877254096708
|
click
|
accessibility
|
NULL
|
Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧ Explorer (⇧⌘E)
Search (⇧⌘F)
Source Control (⌃⇧G)
Run and Debug (⇧⌘D)
Remote Explorer
Extensions (⇧⌘X) - 2 require update
2
Claude Code
Containers
EXPLORER
EXPLORER
Explorer Section: payments-logger [SSH: nas]
Explorer Section: payments-logger [SSH: nas]
PAYMENTS-LOGGER [SSH: NAS]
.claude
backend
prisma
migrations
schema.prisma
src
routes
auth.js
index.js
parser.js
.dockerignore
Dockerfile
package.json
frontend
.env
.env.example
.gitignore
API.md
docker-compose.yml
README.md
Outline Section
OUTLINE
OUTLINE
Timeline Section
TIMELINE
TIMELINE
README.md, Editor Group 1
index.js, preview, Editor Group 1
index.js, preview, Editor Group 1
1. Message that arrives …, Editor Group 2
Problems (⇧⌘M)
PROBLEMS
Output (⇧⌘U)
OUTPUT
Debug Console (⇧⌘Y)
DEBUG CONSOLE
Terminal (⌃`)
TERMINAL
Ports
PORTS
remote SSH: nas
SSH: nas
No Problems
0
0
No Ports Forwarded
0
Analyzing 'index.js' and its dependencies
Analyzing 'index.js' and its dependencies
Notifications
Signed out
Signed out
Screen Reader Optimized
Info: Setting up SSH Host nas: Setting up SSH tunnel
Yes
No
Learn More
Screen reader usage detected. Do you want to enable editor.accessibilitySupport to optimize the editor for screen reader usage?...
|
10398
|
NULL
|
NULL
|
NULL
|
|
13382
|
589
|
31
|
2026-05-09T15:23:29.311466+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-09/1778 /Users/lukas/.screenpipe/data/data/2026-05-09/1778340209311_m1.jpg...
|
Firefox
|
Finance Hub — Personal
|
True
|
finance-hub.lakylak.xyz/outpost.goauthentik.io/sig finance-hub.lakylak.xyz/outpost.goauthentik.io/sign_out...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox (2) - [EMAIL] - Gmail
Inbox (2) - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Select: transactions - db - Adminer
Select: transactions - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
235
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Refresh
Display settings
Sign out
Filters
Filters
Search
Recipient, description…
Source
Status
Type
Tag
From date
dd
/
mm
/
yyyy
Calendar
To date
dd
/
mm
/
yyyy
Calendar
235
transaction
s
·
Total:
10,250.48
EUR
DATE
RECIPIENT
AMOUNT
TAGS
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
RAW DATA
Zdraveyte, ot 01/07/2026 vlizat v sila izmeneni Obshti uslovia, a ot 01/09/2026 - izmenena Tarifa na Banka DSK. Poveche na sayta na bankata, sektsia Izvestia.
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · screenpipe/screenpipe · GitHub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DNS / Nameservers | Hostinger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DNS / Nameservers | Hostinger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: archive.db","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: db.sqlite","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AFFiNE - All In One KnowledgeOS","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AFFiNE - All In One KnowledgeOS","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"All docs · AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All docs · AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Payments Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Inbox (2) - kovaliklukas@gmail.com - Gmail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox (2) - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"(25) Quora","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"(25) Quora","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Finance Hub","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Finance Hub","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Select: transactions - db - Adminer","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select: transactions - db - Adminer","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфони с Unlimited план до 120 € отстъпка | Vivacom","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"VIVACOM","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"VIVACOM","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Code | Claude Platform","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Code | Claude Platform","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Finance Hub","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finance Hub","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"235","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"transaction","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Payments","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Payments","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Upload CSV","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Upload CSV","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Refresh","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Display settings","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Sign out","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Filters","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Filters","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Recipient, description…","depth":10,"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Source","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Status","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Type","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tag","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"From date","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dd","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mm","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"yyyy","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"To date","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dd","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mm","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"yyyy","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"235","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"transaction","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"·","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Total:","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10,250.48","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EUR","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DATE","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"RECIPIENT","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AMOUNT","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TAGS","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"RAW DATA","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Zdraveyte, ot 01/07/2026 vlizat v sila izmeneni Obshti uslovia, a ot 01/09/2026 - izmenena Tarifa na Banka DSK. Poveche na sayta na bankata, sektsia Izvestia.","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.0,"width":0.008680556,"height":0.018888889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.0,"width":0.04548611,"height":0.026666667},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.0,"width":0.02048611,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.0,"width":0.04375,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.0,"width":0.017361112,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.0,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.0,"width":0.008680556,"height":0.018888889},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.0,"width":0.04548611,"height":0.026666667},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.0,"width":0.02048611,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.0,"width":0.04375,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.0,"width":0.017361112,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.0,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.008333334,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.0044444446,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.009444444,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.0033333334,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.009444444,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.0033333334,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.056111112,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.052222222,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.05722222,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.05111111,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.05722222,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.05111111,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.10388889,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.1,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.105,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.09888889,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.105,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.09888889,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.15166667,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.14777778,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.15277778,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.14666666,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.15277778,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.14666666,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.19944444,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.19555555,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.20055556,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.19444445,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.20055556,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.19444445,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.24722221,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.24333334,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.24833333,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.24222222,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.24833333,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.24222222,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.295,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.2911111,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.2961111,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.29,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.2961111,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.29,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.3427778,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.33888888,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.34388888,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.33777776,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.34388888,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.33777776,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.39055556,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.38666666,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.39166668,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.38555557,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.39166668,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.38555557,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.43833333,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.43444446,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.43944445,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.43333334,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.43944445,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.43333334,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.4861111,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.48222223,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.48722222,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.4811111,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.48722222,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.4811111,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.5338889,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.53,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.535,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.5288889,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.535,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.5288889,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.58166665,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.5777778,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.5827778,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.57666665,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.5827778,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.57666665,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.6294444,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.6255556,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.63055557,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.6244444,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.63055557,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.6244444,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.67722225,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.67333335,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.67833334,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.6722222,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.67833334,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.6722222,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.725,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.7211111,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.7261111,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.72,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.7261111,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.72,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.7727778,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.7688889,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.7738889,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.7677778,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.7738889,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.7677778,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Raw data","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"bounds":{"left":0.0,"top":0.82055557,"width":0.008680556,"height":0.018888889},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send","depth":13,"bounds":{"left":0.19652778,"top":0.81666666,"width":0.04548611,"height":0.026666667},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Send","depth":14,"bounds":{"left":0.21458334,"top":0.82166666,"width":0.02048611,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Skip","depth":13,"bounds":{"left":0.24479167,"top":0.8155556,"width":0.04375,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip","depth":14,"bounds":{"left":0.26354167,"top":0.82166666,"width":0.017361112,"height":0.016666668},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":13,"bounds":{"left":0.29131943,"top":0.8155556,"width":0.018055556,"height":0.028888889},"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"—","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-9069115945911979084
|
1873538485670552419
|
click
|
accessibility
|
NULL
|
Pull requests · screenpipe/screenpipe · GitHub
Pul Pull requests · screenpipe/screenpipe · GitHub
Pull requests · screenpipe/screenpipe · GitHub
DNS / Nameservers | Hostinger
DNS / Nameservers | Hostinger
Nginx Proxy Manager
Nginx Proxy Manager
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
screenpipe/.claude/skills at main · screenpipe/screenpipe · GitHub
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
AFFiNE - All In One KnowledgeOS
AFFiNE - All In One KnowledgeOS
All docs · AFFiNE
All docs · AFFiNE
Payments Logger
Payments Logger
Inbox (2) - [EMAIL] - Gmail
Inbox (2) - [EMAIL] - Gmail
(25) Quora
(25) Quora
Location Logger
Location Logger
Finance Hub
Finance Hub
Finance Hub
Finance Hub
Close tab
Select: transactions - db - Adminer
Select: transactions - db - Adminer
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
Stop Losing Notes: Pick A Cross-Device App That Syncs | AFFiNE
VIVACOM
VIVACOM
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
Смартфони с Unlimited план до 120 € отстъпка | Vivacom
VIVACOM
VIVACOM
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Смартфон SAMSUNG GALAXY A57 5G 256GB | Vivacom
Claude Code | Claude Platform
Claude Code | Claude Platform
Claude
Claude
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Finance Hub
Finance Hub
235
transaction
s
Payments
Payments
Upload CSV
Upload CSV
Refresh
Display settings
Sign out
Filters
Filters
Search
Recipient, description…
Source
Status
Type
Tag
From date
dd
/
mm
/
yyyy
Calendar
To date
dd
/
mm
/
yyyy
Calendar
235
transaction
s
·
Total:
10,250.48
EUR
DATE
RECIPIENT
AMOUNT
TAGS
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
RAW DATA
Zdraveyte, ot 01/07/2026 vlizat v sila izmeneni Obshti uslovia, a ot 01/09/2026 - izmenena Tarifa na Banka DSK. Poveche na sayta na bankata, sektsia Izvestia.
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—
—
Raw data
—
Send
Send
Skip
Skip
Delete
—...
|
13381
|
NULL
|
NULL
|
NULL
|
|
17326
|
770
|
1
|
2026-05-11T10:16:50.580661+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778494610580_m1.jpg...
|
Notion Calendar
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelplih§ Support Daily • in 1h 44 mDOCKERO 81DEV (docker)H82APP (-zsh)DEV (docker)X3-zshl84-zsh100%8• Mon 11 May 13:16:50181screenpipe"O ₴6configcachecompiledeventsroutesviewsjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00:stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00:stoppedjiminny-worker-processing-5:jiminny-worker-processing-5_00:stoppedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-emails:worker-emails_00:stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00:startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00:startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny: debugll88510.53ms DONE128.25ms DONE1.73ms DONE1.07ms DONE1.45ms DONE5.46ms DONEDEV...
|
NULL
|
-9066277419738111639
|
NULL
|
visual_change
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelplih§ Support Daily • in 1h 44 mDOCKERO 81DEV (docker)H82APP (-zsh)DEV (docker)X3-zshl84-zsh100%8• Mon 11 May 13:16:50181screenpipe"O ₴6configcachecompiledeventsroutesviewsjiminny-worker-processing-2:jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00:stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00:stoppedjiminny-worker-processing-5:jiminny-worker-processing-5_00:stoppedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-emails:worker-emails_00:stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00:startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00:startedroot@docker_lamp_1:/home/jiminny#php artisan jiminny: debugll88510.53ms DONE128.25ms DONE1.73ms DONE1.07ms DONE1.45ms DONE5.46ms DONEDEV...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
16754
|
749
|
7
|
2026-05-11T09:22:32.377073+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778491352377_m2.jpg...
|
Slack
|
Petko Kashinski (DM) - Jiminny Inc - 4 new items - Petko Kashinski (DM) - Jiminny Inc - 4 new items - Slack...
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Petko Kashinski
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Galya Dimitrova
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Ves
Aneliya Angelova
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Apr 21st at 1:54:17 PM
1:54 PM
аз не съм чувал за такава но не съм и работил по planhat
Apr 21st at 1:54:45 PM
1:54
ок мерси, ще ти пиша, или в тикет направо когато сме готови
Petko Kashinski
Apr 21st at 1:56:12 PM
1:56 PM
oks thx
Jump to date
Petko Kashinski
Apr 22nd at 4:48:19 PM
4:48 PM
Лукас
Apr 22nd at 4:48:25 PM
4:48
Имаш ли минутка за бърз хъдъл :?
Lukas Kovalik
Apr 22nd at 6:49:40 PM
6:49 PM
здрасти Петко, до сега бях в среща
Apr 22nd at 6:49:53 PM
6:49
какво става
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Apr 22nd at 6:50:38 PM
6:50 PM
Няма проблем
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Apr 22nd at 6:50:40 PM
6:50
Оправих се
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
Apr 22nd at 6:50:56 PM
6:50 PM
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
Petko Kashinski
Today at 12:11:27 PM
12:11 PM
Лукас
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 12:11:30 PM
12:11
Имаш ли 2 минутки ?
(edited)
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:13:47 PM
12:13 PM
здрасти да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:13:55 PM
12:13 PM
Може ли да звънна?
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:13:57 PM
12:13 PM
да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
A huddle happened
Today at 12:14:01 PM
12:14 PM
You and
Petko Kashinski
were in the huddle for
8m
.
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:21:31 PM
12:21 PM
playbackVisited
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
loading…
Petko Kashinski is typing...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.0056515955,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"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.0029920214,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.0066489363,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.0029920214,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.0076462766,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"bounds":{"left":0.0029920214,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.004986702,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.005319149,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.0076462766,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"bounds":{"left":0.0029920214,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.0076462766,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.007978723,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.009973404,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"bounds":{"left":0.0029920214,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.00731383,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.00731383,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.00930851,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"bounds":{"left":0.0029920214,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.006981383,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.00731383,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.010638298,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"bounds":{"left":0.042220745,"top":0.09177973,"width":0.025598405,"height":0.005586592},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"bounds":{"left":0.042220745,"top":0.105347164,"width":0.015957447,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.105347164,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.04488032,"top":0.105347164,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"bounds":{"left":0.042220745,"top":0.12769353,"width":0.022938829,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.12769353,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.043550532,"top":0.12769353,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"bounds":{"left":0.042220745,"top":0.15003991,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.15003991,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.045212764,"top":0.15003991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"bounds":{"left":0.042220745,"top":0.17238627,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.17238627,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.045212764,"top":0.17238627,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"bounds":{"left":0.042220745,"top":0.19473264,"width":0.01662234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.19473264,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.044215426,"top":0.19473264,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"bounds":{"left":0.042220745,"top":0.21707901,"width":0.01761968,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.21707901,"width":0.0016622341,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.043882977,"top":0.21707901,"width":0.015957447,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"bounds":{"left":0.042220745,"top":0.23942538,"width":0.024268618,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.23942538,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.04454787,"top":0.23942538,"width":0.021941489,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"bounds":{"left":0.042220745,"top":0.26177174,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.26177174,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.04454787,"top":0.26177174,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"bounds":{"left":0.042220745,"top":0.28411812,"width":0.024268618,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.28411812,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.044215426,"top":0.28411812,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"bounds":{"left":0.042220745,"top":0.3064645,"width":0.04488032,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.3064645,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.044215426,"top":0.3064645,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":23,"bounds":{"left":0.042220745,"top":0.35913807,"width":0.034242023,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.35913807,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.045212764,"top":0.35913807,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"bounds":{"left":0.042220745,"top":0.38148445,"width":0.03756649,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.38148445,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.04488032,"top":0.38148445,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"bounds":{"left":0.042220745,"top":0.4038308,"width":0.026263298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.4038308,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.045212764,"top":0.4038308,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"bounds":{"left":0.042220745,"top":0.42617717,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.42617717,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.046210106,"top":0.42617717,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"bounds":{"left":0.042220745,"top":0.44852355,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.44852355,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.045877658,"top":0.44852355,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.042220745,"top":0.4708699,"width":0.03756649,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.4708699,"width":0.0033244682,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.045545213,"top":0.4708699,"width":0.034242023,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"bounds":{"left":0.07945479,"top":0.4708699,"width":0.0063164895,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"bounds":{"left":0.08211436,"top":0.4708699,"width":0.014295213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.08211436,"top":0.4708699,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.08610372,"top":0.4708699,"width":0.028922873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"bounds":{"left":0.09607713,"top":0.4884278,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"bounds":{"left":0.09607713,"top":0.4884278,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11735372,"top":0.4708699,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.1200133,"top":0.4708699,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":23,"bounds":{"left":0.042220745,"top":0.49321628,"width":0.028922873,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.49321628,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.04488032,"top":0.49321628,"width":0.026263298,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":23,"bounds":{"left":0.042220745,"top":0.51556265,"width":0.0076462766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.51556265,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.045212764,"top":0.51556265,"width":0.004986702,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.042220745,"top":0.53790903,"width":0.03756649,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.53790903,"width":0.0033244682,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.045545213,"top":0.53790903,"width":0.034242023,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":23,"bounds":{"left":0.042220745,"top":0.5602554,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.5602554,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.044215426,"top":0.5602554,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"bounds":{"left":0.042220745,"top":0.5826017,"width":0.030585106,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.5826017,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.04488032,"top":0.5826017,"width":0.026928192,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"bounds":{"left":0.07413564,"top":0.5826017,"width":0.00831117,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.07446808,"top":0.5826017,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.07679521,"top":0.5826017,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"bounds":{"left":0.042220745,"top":0.63527536,"width":0.022273935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.63527536,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.04454787,"top":0.63527536,"width":0.019946808,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"bounds":{"left":0.042220745,"top":0.6576217,"width":0.011968086,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.6576217,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.04488032,"top":0.6576217,"width":0.009640957,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"bounds":{"left":0.042220745,"top":0.67996806,"width":0.03025266,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.67996806,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.045877658,"top":0.67996806,"width":0.032912236,"height":0.014365523}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.10206117,"top":0.09177973,"width":0.030585106,"height":0.030327214},"on_screen":true,"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.111369684,"top":0.10055866,"width":0.01861702,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.111369684,"top":0.10055866,"width":0.0039893617,"height":0.012769354}},{"char_start":1,"char_count":7,"bounds":{"left":0.115359046,"top":0.10055866,"width":0.014960106,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"bounds":{"left":0.13397606,"top":0.09177973,"width":0.033909574,"height":0.030327214},"on_screen":true,"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.14328457,"top":0.10055866,"width":0.021941489,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14328457,"top":0.10055866,"width":0.0033244682,"height":0.012769354}},{"char_start":1,"char_count":9,"bounds":{"left":0.1462766,"top":0.10055866,"width":0.019281914,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":17,"bounds":{"left":0.16921543,"top":0.09177973,"width":0.020944148,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":19,"bounds":{"left":0.17852394,"top":0.10055866,"width":0.008976064,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.17852394,"top":0.10055866,"width":0.0026595744,"height":0.012769354}},{"char_start":1,"char_count":4,"bounds":{"left":0.18118352,"top":0.10055866,"width":0.0063164895,"height":0.012769354}}],"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.19115691,"top":0.09177973,"width":0.010970744,"height":0.030327214},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"bounds":{"left":0.096409574,"top":0.0518755,"width":0.015625,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"bounds":{"left":0.096409574,"top":0.0518755,"width":0.0076462766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"bounds":{"left":0.096409574,"top":0.0518755,"width":0.013962766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:54:17 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:54 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"аз не съм чувал за такава но не съм и работил по planhat","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:54:45 PM","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:54","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ок мерси, ще ти пиша, или в тикет направо когато сме готови","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:56:12 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:56 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"oks thx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"bounds":{"left":0.12932181,"top":0.12689546,"width":0.05817819,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 4:48:19 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4:48 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Лукас","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 4:48:25 PM","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4:48","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Имаш ли минутка за бърз хъдъл :?","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.11801862,"top":0.11572227,"width":0.030917553,"height":0.008778931},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15525267,"top":0.11572227,"width":0.0029920214,"height":0.0071827616},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:49:40 PM","depth":24,"bounds":{"left":0.15791224,"top":0.11572227,"width":0.015292553,"height":0.006384677},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:49 PM","depth":25,"bounds":{"left":0.15791224,"top":0.11572227,"width":0.015292553,"height":0.006384677},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"здрасти Петко, до сега бях в среща","depth":25,"bounds":{"left":0.11801862,"top":0.12609737,"width":0.08144947,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.12609737,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":33,"bounds":{"left":0.12034574,"top":0.12609737,"width":0.07912234,"height":0.014365523}}],"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:49:53 PM","depth":25,"bounds":{"left":0.107380316,"top":0.15243416,"width":0.007978723,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:49","depth":26,"bounds":{"left":0.107380316,"top":0.15243416,"width":0.007978723,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.107380316,"top":0.15243416,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.109707445,"top":0.15243416,"width":0.005984043,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"какво става","depth":25,"bounds":{"left":0.11801862,"top":0.15003991,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.15003991,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.120678194,"top":0.15003991,"width":0.023936171,"height":0.014365523}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.12529927,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.12529927,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"bounds":{"left":0.11801862,"top":0.17238627,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15392287,"top":0.17398244,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:50:38 PM","depth":24,"bounds":{"left":0.15658244,"top":0.1763767,"width":0.014960106,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50 PM","depth":25,"bounds":{"left":0.15658244,"top":0.1763767,"width":0.014960106,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.1763767,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.15890957,"top":0.1763767,"width":0.012965426,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Няма проблем","depth":25,"bounds":{"left":0.11801862,"top":0.1915403,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.1915403,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.12200798,"top":0.1915403,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.15881884,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.15881884,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Apr 22nd at 6:50:40 PM","depth":25,"bounds":{"left":0.107380316,"top":0.21787709,"width":0.007978723,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50","depth":26,"bounds":{"left":0.107380316,"top":0.21787709,"width":0.007978723,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.107380316,"top":0.21787709,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.109707445,"top":0.21787709,"width":0.005984043,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Оправих се","depth":25,"bounds":{"left":0.11801862,"top":0.21548285,"width":0.027260639,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.21548285,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.12200798,"top":0.21548285,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.19074222,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.19074222,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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.11801862,"top":0.23782921,"width":0.030917553,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15525267,"top":0.23942538,"width":0.0029920214,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:50:56 PM","depth":24,"bounds":{"left":0.15791224,"top":0.24181964,"width":0.015292553,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50 PM","depth":25,"bounds":{"left":0.15791224,"top":0.24181964,"width":0.015292553,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15824468,"top":0.24181964,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.16057181,"top":0.24181964,"width":0.012965426,"height":0.011971269}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.22426178,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.22426178,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"bounds":{"left":0.14594415,"top":0.2952913,"width":0.025265958,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"bounds":{"left":0.11801862,"top":0.3264166,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15392287,"top":0.32801276,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:11:27 PM","depth":24,"bounds":{"left":0.15658244,"top":0.33040702,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11 PM","depth":25,"bounds":{"left":0.15658244,"top":0.33040702,"width":0.017287234,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.33040702,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.15890957,"top":0.33040702,"width":0.015292553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Лукас","depth":25,"bounds":{"left":0.11801862,"top":0.34557062,"width":0.013630319,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.34557062,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.12167553,"top":0.34557062,"width":0.009973404,"height":0.014365523}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.31284916,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.31284916,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:11:30 PM","depth":25,"bounds":{"left":0.105053194,"top":0.3719074,"width":0.010305851,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11","depth":26,"bounds":{"left":0.105053194,"top":0.3719074,"width":0.010305851,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Имаш ли 2 минутки ?","depth":25,"bounds":{"left":0.11801862,"top":0.36951315,"width":0.049534574,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"bounds":{"left":0.16755319,"top":0.37110934,"width":0.0013297872,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":25,"bounds":{"left":0.16855054,"top":0.37110934,"width":0.01462766,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"bounds":{"left":0.18284574,"top":0.37110934,"width":0.0013297872,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.34477255,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.34477255,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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.11801862,"top":0.39185953,"width":0.030917553,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15525267,"top":0.3934557,"width":0.0029920214,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:47 PM","depth":24,"bounds":{"left":0.15791224,"top":0.39584997,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"bounds":{"left":0.15791224,"top":0.39584997,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"здрасти да","depth":25,"bounds":{"left":0.11801862,"top":0.41101357,"width":0.025265958,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.3782921,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.3782921,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"bounds":{"left":0.11801862,"top":0.43335995,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15392287,"top":0.4349561,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:55 PM","depth":24,"bounds":{"left":0.15658244,"top":0.43735036,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"bounds":{"left":0.15658244,"top":0.43735036,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Може ли да звънна?","depth":25,"bounds":{"left":0.11801862,"top":0.45251396,"width":0.046875,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.4197925,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.4197925,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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.11801862,"top":0.47486034,"width":0.030917553,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15525267,"top":0.4764565,"width":0.0029920214,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:57 PM","depth":24,"bounds":{"left":0.15791224,"top":0.47885075,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"bounds":{"left":0.15791224,"top":0.47885075,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да","depth":25,"bounds":{"left":0.11801862,"top":0.49401435,"width":0.0056515955,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.4612929,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.4612929,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"A huddle happened","depth":24,"bounds":{"left":0.11801862,"top":0.5179569,"width":0.043218084,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.1612367,"top":0.5179569,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:14:01 PM","depth":24,"bounds":{"left":0.16389628,"top":0.5203512,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:14 PM","depth":25,"bounds":{"left":0.16389628,"top":0.5203512,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"You and","depth":24,"bounds":{"left":0.11801862,"top":0.5355148,"width":0.01861702,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":24,"bounds":{"left":0.13663563,"top":0.5355148,"width":0.034574468,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"were in the huddle for","depth":24,"bounds":{"left":0.11801862,"top":0.5355148,"width":0.09507979,"height":0.031923383},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"8m","depth":24,"bounds":{"left":0.12533244,"top":0.55307263,"width":0.00731383,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".","depth":24,"bounds":{"left":0.13231383,"top":0.55307263,"width":0.0013297872,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.5027933,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.5027933,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"bounds":{"left":0.11801862,"top":0.575419,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15392287,"top":0.57701516,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:21:31 PM","depth":24,"bounds":{"left":0.15658244,"top":0.5794094,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:21 PM","depth":25,"bounds":{"left":0.15658244,"top":0.5794094,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"playbackVisited","depth":25,"bounds":{"left":0.11801862,"top":0.594573,"width":0.034242023,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.56185156,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.56185156,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":23,"bounds":{"left":0.10372341,"top":0.6272945,"width":0.109707445,"height":0.030327214},"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"loading…","depth":11,"bounds":{"left":0.0,"top":0.7126895,"width":0.018949468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski is typing","depth":11,"bounds":{"left":0.0,"top":0.7126895,"width":0.019946808,"height":0.0007980846},"on_screen":true,"role_description":"text"}]...
|
-9066207687685814032
|
-3879404872211726252
|
visual_change
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Petko Kashinski
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Galya Dimitrova
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Ves
Aneliya Angelova
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Apr 21st at 1:54:17 PM
1:54 PM
аз не съм чувал за такава но не съм и работил по planhat
Apr 21st at 1:54:45 PM
1:54
ок мерси, ще ти пиша, или в тикет направо когато сме готови
Petko Kashinski
Apr 21st at 1:56:12 PM
1:56 PM
oks thx
Jump to date
Petko Kashinski
Apr 22nd at 4:48:19 PM
4:48 PM
Лукас
Apr 22nd at 4:48:25 PM
4:48
Имаш ли минутка за бърз хъдъл :?
Lukas Kovalik
Apr 22nd at 6:49:40 PM
6:49 PM
здрасти Петко, до сега бях в среща
Apr 22nd at 6:49:53 PM
6:49
какво става
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Apr 22nd at 6:50:38 PM
6:50 PM
Няма проблем
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Apr 22nd at 6:50:40 PM
6:50
Оправих се
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
Apr 22nd at 6:50:56 PM
6:50 PM
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
Petko Kashinski
Today at 12:11:27 PM
12:11 PM
Лукас
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 12:11:30 PM
12:11
Имаш ли 2 минутки ?
(edited)
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:13:47 PM
12:13 PM
здрасти да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:13:55 PM
12:13 PM
Може ли да звънна?
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:13:57 PM
12:13 PM
да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
A huddle happened
Today at 12:14:01 PM
12:14 PM
You and
Petko Kashinski
were in the huddle for
8m
.
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:21:31 PM
12:21 PM
playbackVisited
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
loading…
Petko Kashinski is typing
HomeActivityMoreSlackcalVIewJiminny ... ~# general# jiminny-bg# platform-tickets# product launches# random# releasesi sona-otnce# support# thank-vous# the people of jimi..6- Direct messages.Petko Kashinski8 Stefka StovanovaeVasil Vasiley.Nikolay IvanovGalva Dimitrova3 Aneliya Angelova.Stovan TaneyVesf Aneliva AngelovaJames GrahamLukas Kovali.::: Apps" Jira Cloud8 ToastExportController.php© FrontendController.ph| 112T FrontendControllerTra 118@ GeocodingController.p 119(C) HealthCheckControlleiP LiveCoachController.pl 12g© MissingTeamControlle 120C) MobileController.oho© NotificationController.1 1z4© NotificationProviderCo 145Ye) PlavbackControlier ohg DlavlistController nhn1A4IO S(C) PucherController nhng SlackController nhnmistonWindowhelp@ Describe what you are looking for? Petko KashinskiMessagest Add canvas@ FilesWednesday. April 22nd ~ рещаKakbo clabaPetko Kashinski 6.50 PMlНяма проблемОправих се сLukas Kovalik6:50 PMPetko Kashinski 12:11 PMЛукасИмаш ли ? минутии ? (oditod)Lukas Kovallk 12.12 PMздрасти даPetkо Kachincki 12.12 PMМоже ли да звънна?Lukas Kovalik M 12:13 PMA huddle hanbened 12:14 PNYou and Petko Kashinski were in the huddlefor 8m.Petko Kashinski 12.21 PNolavbackVisitedMessage Petko Kashinski+ Aa• suppont Dally • In 2n 30m100% 2• Mon 11 May 12:22:32+0 ..ontceneratedevent.onp© UserAutomatedReportsController.phpHubSpot/Service.php© SyncRelatedActivityManager.phpRematchActivityOnCrmObjectDetach.phgС) Cпескапакеtгукemotematch.phgIvityservice.oho( RateLimitException.phpC) MatchCrmData.phpC) CrmObiectsResolver.phoFrontendControllerMA6X3AYivity, PlaybackPageTransformer $transformer, Request Srequest): arraylstr:avlist' = Sth1s->getPreloadedPlavu1stSactiv1tv)^1'J'tracks'0) ^iks'Event to Planhat without slowina theFter the response is sent backvice->track(ctivity->getIdOactivity->getUuid,A SF (jiminny@localhost]4 HS_local (jiminny@localhost]# console [PKob.# console leu)# console [slAGiNg)2026-05-07 14:21:15] local.INF0: [Hubspot] DEBUG Getting headers {MMi9 AYheaders'1"Vace". "Inu,ur May 2020 14.21.19 6Ml"Jn"concenc-lyoe. apolicacion/ison.charser=utt-on"Transfer-Encoding": ["chunked"]."CF-Ray": ["9f80deb8db60dc3a-SOF"]."CF-Cache-Status": L"DYNAMIC"J,"Strict-Transport-Secur1ty":"max-aqe=31536000* 1ncludeSubDomains: preload")nacceot-encodino""access-control-allow-credentials": "false"."server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",cfr;desc=|"9f80deb8e7c6dc3a-1AD\""J,"x-content-tvoe-ootions":"nosniff"."x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],"Set-Cookie":["__cf_bm=StUrtdQgXVrik50pdqF6hZVYKhzTnQBidvMabeCtm0Y-1778163675-[IP_ADDRESS]-May-26 14:51:15 GMT; domain=.hubapi.com; Http0nly; Secure; SameSite=None"],"Report-To":["{"endnoints".("url\":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=NYAlsVTP0fYm32qrSDjxYE4sd2RV("group\":\"cf-nel\".("max_age\":604800}"],"NEL":["{"success_fraction\":0.01,reportto. "cr-nel,"max agel ":604800}"].'Server":["cloudflare"]}} {"correlation_1d":"95256555-ec98-4541-b9za-adta/Sboyeab","trace_10":"C/AD8565-905t-4604-9405-0e5b551e5545aybackbata']ravorited'CascadeHubspot Rate Limit ReE. Deaicatea low-concurrency worker poolRun only 5 workers for analytics low so concurrency naturally matches the 5 RPS limitEbashpho artisan queue:work --queue=analvtics low --tries= -max-iobs=0 --processes=5Effect: 5 workers x 1 successful op/sec = 5/sec. No rate-limit storms because we're under the limit by design. Each worker rarely sees a 429.Trade-oris•Slower throughput (still b/sec ceiling = 5.5 hours tor 100k• Other iobs on this queue comnete with the bottlleneckWorks, but requires Horizon config changesF. Pre-flight cache check at job entry (mentioned earlier)Eliminates the DB.transaction churn.from.cache-hit cvcles.Doesnit chande.the throughnut.ceilina.but.reduces.cost.during.a.storm.to.almost.nothinaEasy win. Pairs with all other optionsG. Filter unmatchable activities betore dispatchIf manv activities have no email/ohone/name to match. dispatchina them is pure waste.• phpActivity::needsCrmMatch()›whereHas("participants', fn (Sq) = $q->whereNotNull('email")->orWhereNotNull('phone"))→each(fn (sa) => MatchActivitvCrmData::dispatch(Sa->id)):If 30% of the 100k are unmatchable (no contact info), removing them gets you to 70k - still over 9k cap, but closer.Effort: low if a querv-side filter is feasibleRecommended combinationFor maximum RoI1. A hatch endnoints) — 100x throuahnut. Solves the nroblem2. B (dispatch throttling) - defense in depth. prevents future storms.3. C (lookup caching) - reduces redundant API calls.4. F (pre-flight cache check) - eliminates DB churn during inevitable stormsWith A + B alone, the 100k → 9k problem becomes 100k → 100k completed in ~3-10 minutes, depending on caching efficiency.A is the leverage point. Without batch endpoints, you're brute-forcing through a 5 RPS hose. With them, the hose is 500 matches/sec.SummaryRace window: 5-10 wasted real APl calls per cache iil cycle, Bounded, ~15k calls wastedlin 30 min (vs 441k without cache). Acceptables can be tiahtened with aprobe lock if neededHubSpot-named middleware on multi-CRM iob: no functional issue for HubSpot. Salesforce/Pinedrive rate-limits ao throuch the wrond nath (treated as real100k → 9k bottleneck: not a rate-limiter problem, an architectural one. The fix is batch endpoints + dispatch throttling, not more aggressive retry logic.=> SvLewprivate function getPreloadedPlaylist(Activity Sactivity): arrayt...hOthrows AuthonizationEycentionGET Inlavlict[activitv) m2u8 fnlavlict1public function playlist(Activity $activity): Response{...}Ask anvthing (84D)+ « CodeClaude Onus 4.7 Mediumfo 4 spaces...
|
16752
|
NULL
|
NULL
|
NULL
|
|
16755
|
748
|
6
|
2026-05-11T09:22:32.589488+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778491352589_m1.jpg...
|
Slack
|
Petko Kashinski (DM) - Jiminny Inc - 4 new items - Petko Kashinski (DM) - Jiminny Inc - 4 new items - Slack...
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Petko Kashinski
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Galya Dimitrova
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Ves
Aneliya Angelova
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Apr 21st at 1:54:17 PM
1:54 PM
аз не съм чувал за такава но не съм и работил по planhat
Apr 21st at 1:54:45 PM
1:54
ок мерси, ще ти пиша, или в тикет направо когато сме готови
Petko Kashinski
Apr 21st at 1:56:12 PM
1:56 PM
oks thx
Jump to date
Petko Kashinski
Apr 22nd at 4:48:19 PM
4:48 PM
Лукас
Apr 22nd at 4:48:25 PM
4:48
Имаш ли минутка за бърз хъдъл :?
Lukas Kovalik
Apr 22nd at 6:49:40 PM
6:49 PM
здрасти Петко, до сега бях в среща
Apr 22nd at 6:49:53 PM
6:49
какво става
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Apr 22nd at 6:50:38 PM
6:50 PM
Няма проблем
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Apr 22nd at 6:50:40 PM
6:50
Оправих се
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
Apr 22nd at 6:50:56 PM
6:50 PM
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
Petko Kashinski
Today at 12:11:27 PM
12:11 PM
Лукас
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 12:11:30 PM
12:11
Имаш ли 2 минутки ?
(edited)
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:13:47 PM
12:13 PM
здрасти да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:13:55 PM
12:13 PM
Може ли да звънна?
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:13:57 PM
12:13 PM
да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
A huddle happened
Today at 12:14:01 PM
12:14 PM
You and
Petko Kashinski
were in the huddle for
8m
.
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:21:31 PM
12:21 PM
playbackVisited
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
loading…
Petko Kashinski is typing...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":20,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":17,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":19,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:54:17 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:54 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"аз не съм чувал за такава но не съм и работил по planhat","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:54:45 PM","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:54","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ок мерси, ще ти пиша, или в тикет направо когато сме готови","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:56:12 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:56 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"oks thx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 4:48:19 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4:48 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Лукас","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 4:48:25 PM","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4:48","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Имаш ли минутка за бърз хъдъл :?","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:49:40 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:49 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"здрасти Петко, до сега бях в среща","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:49:53 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:49","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"какво става","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:50:38 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Няма проблем","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Apr 22nd at 6:50:40 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Оправих се","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:50:56 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:11:27 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Лукас","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:11:30 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Имаш ли 2 минутки ?","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:47 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"здрасти да","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:55 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Може ли да звънна?","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:57 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"A huddle happened","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:14:01 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:14 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"You and","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"were in the huddle for","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"8m","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:21:31 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:21 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"playbackVisited","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"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,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":true,"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,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":23,"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"loading…","depth":11,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski is typing","depth":11,"on_screen":true,"role_description":"text"}]...
|
-9066207687685814032
|
-3879404872211726252
|
click
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Petko Kashinski
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Galya Dimitrova
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Ves
Aneliya Angelova
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Apr 21st at 1:54:17 PM
1:54 PM
аз не съм чувал за такава но не съм и работил по planhat
Apr 21st at 1:54:45 PM
1:54
ок мерси, ще ти пиша, или в тикет направо когато сме готови
Petko Kashinski
Apr 21st at 1:56:12 PM
1:56 PM
oks thx
Jump to date
Petko Kashinski
Apr 22nd at 4:48:19 PM
4:48 PM
Лукас
Apr 22nd at 4:48:25 PM
4:48
Имаш ли минутка за бърз хъдъл :?
Lukas Kovalik
Apr 22nd at 6:49:40 PM
6:49 PM
здрасти Петко, до сега бях в среща
Apr 22nd at 6:49:53 PM
6:49
какво става
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Apr 22nd at 6:50:38 PM
6:50 PM
Няма проблем
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Apr 22nd at 6:50:40 PM
6:50
Оправих се
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
Apr 22nd at 6:50:56 PM
6:50 PM
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
Petko Kashinski
Today at 12:11:27 PM
12:11 PM
Лукас
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 12:11:30 PM
12:11
Имаш ли 2 минутки ?
(edited)
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:13:47 PM
12:13 PM
здрасти да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:13:55 PM
12:13 PM
Може ли да звънна?
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:13:57 PM
12:13 PM
да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
A huddle happened
Today at 12:14:01 PM
12:14 PM
You and
Petko Kashinski
were in the huddle for
8m
.
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:21:31 PM
12:21 PM
playbackVisited
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
loading…
Petko Kashinski is typing
SlackFile Edit ViewGoHistoryWindowHelp<DEV (docker)• *з.• Support Daily • in 2h 38 mDOCKER881DEV (docker)882APP (-zsh)masterJY-20818-move-AJ-reports-to-separated-datadog-metricJY-20773-fix-automated-reports-user-pilot-trackingJY-20157-AJ-report-not-send-notificationJY-20508-notify-before-AJ-report-expirationJY-20372-ai-reports-promotion-pagesJY-20352-sync-opportunities-without-a-local-owner-user-id-is-nullJY-20738-debug-AJ-tracking-UPoNtreating-up hout-e- ocat omer- user-id-is-muttJY-18909-automated-reports-ask-jiminnyJY-20692-fix-integration-app-[API_KEY] k-ake-webhook-strategy-defaultJY-s-opportunity-sync-strategy-webhook-basedJY-Сoруnity-without-noteJY-nity-importJY-Copy to clipboard (#C) *ch-on-deleted-groupsJY-JY-verted-leads-when-matchingJY-20150-skip-push-summary-on-summary-ready-1f-autologJY-20132-fix-note-encodingJY-19792-clean-logslukas@Lukas-Kovaliks-MacBook-Pro-Jiminny~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ devroot@docker_lamp_1:/home/jiminny#-zsh84-zsh885100% <78• Mon 11 May 12:22:32181screenpipe"#6DEV...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
16758
|
749
|
9
|
2026-05-11T09:22:38.422904+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778491358422_m2.jpg...
|
Slack
|
Petko Kashinski (DM) - Jiminny Inc - 4 new items - Petko Kashinski (DM) - Jiminny Inc - 4 new items - Slack...
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Petko Kashinski
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Galya Dimitrova
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Ves
Aneliya Angelova
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Apr 21st at 1:54:17 PM
1:54 PM
аз не съм чувал за такава но не съм и работил по planhat
Apr 21st at 1:54:45 PM
1:54
ок мерси, ще ти пиша, или в тикет направо когато сме готови
Petko Kashinski
Apr 21st at 1:56:12 PM
1:56 PM
oks thx
Jump to date
Petko Kashinski
Apr 22nd at 4:48:19 PM
4:48 PM
Лукас
Apr 22nd at 4:48:25 PM
4:48
Имаш ли минутка за бърз хъдъл :?
Lukas Kovalik
Apr 22nd at 6:49:40 PM
6:49 PM
здрасти Петко, до сега бях в среща
Apr 22nd at 6:49:53 PM
6:49
какво става
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Apr 22nd at 6:50:38 PM
6:50 PM
Няма проблем
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Apr 22nd at 6:50:40 PM
6:50
Оправих се
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
Apr 22nd at 6:50:56 PM
6:50 PM
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
Petko Kashinski
Today at 12:11:27 PM
12:11 PM
Лукас
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 12:11:30 PM
12:11
Имаш ли 2 минутки ?
(edited)
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:13:47 PM
12:13 PM
здрасти да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:13:55 PM
12:13 PM
Може ли да звънна?
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:13:57 PM
12:13 PM
да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
A huddle happened
Today at 12:14:01 PM
12:14 PM
You and
Petko Kashinski
were in the huddle for
8m
.
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:21:31 PM
12:21 PM
playbackVisited
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
loading…
Petko Kashinski is typing...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.0056515955,"top":0.058260176,"width":0.011968086,"height":0.028731046},"on_screen":true,"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.0029920214,"top":0.10055866,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.0066489363,"top":0.13806863,"width":0.009973404,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.0029920214,"top":0.15482841,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.0076462766,"top":0.19233839,"width":0.007978723,"height":0.0103751},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"bounds":{"left":0.0029920214,"top":0.20909816,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.004986702,"top":0.24660814,"width":0.012965426,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.005319149,"top":0.24660814,"width":0.0026595744,"height":0.011173184}},{"char_start":1,"char_count":7,"bounds":{"left":0.0076462766,"top":0.24660814,"width":0.010638298,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"bounds":{"left":0.0029920214,"top":0.26336792,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.0076462766,"top":0.3008779,"width":0.0076462766,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.007978723,"top":0.3008779,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.009973404,"top":0.3008779,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"bounds":{"left":0.0029920214,"top":0.31763768,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.00731383,"top":0.35514766,"width":0.008643617,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.00731383,"top":0.35514766,"width":0.0019946808,"height":0.011173184}},{"char_start":1,"char_count":4,"bounds":{"left":0.00930851,"top":0.35514766,"width":0.0066489363,"height":0.011173184}}],"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"bounds":{"left":0.0029920214,"top":0.3719074,"width":0.017287234,"height":0.054269753},"on_screen":true,"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.006981383,"top":0.4094174,"width":0.008976064,"height":0.0103751},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.00731383,"top":0.4094174,"width":0.0033244682,"height":0.011173184}},{"char_start":1,"char_count":3,"bounds":{"left":0.010638298,"top":0.4094174,"width":0.0056515955,"height":0.011173184}}],"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"bounds":{"left":0.042220745,"top":0.09177973,"width":0.025598405,"height":0.005586592},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"bounds":{"left":0.042220745,"top":0.105347164,"width":0.015957447,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.105347164,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.04488032,"top":0.105347164,"width":0.013297873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"bounds":{"left":0.042220745,"top":0.12769353,"width":0.022938829,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.12769353,"width":0.0013297872,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.043550532,"top":0.12769353,"width":0.021609042,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"bounds":{"left":0.042220745,"top":0.15003991,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.15003991,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.045212764,"top":0.15003991,"width":0.031914894,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"bounds":{"left":0.042220745,"top":0.17238627,"width":0.03856383,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.17238627,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.045212764,"top":0.17238627,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"bounds":{"left":0.042220745,"top":0.19473264,"width":0.01662234,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.19473264,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":5,"bounds":{"left":0.044215426,"top":0.19473264,"width":0.014960106,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"bounds":{"left":0.042220745,"top":0.21707901,"width":0.01761968,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.21707901,"width":0.0016622341,"height":0.014365523}},{"char_start":1,"char_count":7,"bounds":{"left":0.043882977,"top":0.21707901,"width":0.015957447,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"bounds":{"left":0.042220745,"top":0.23942538,"width":0.024268618,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.23942538,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.04454787,"top":0.23942538,"width":0.021941489,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"bounds":{"left":0.042220745,"top":0.26177174,"width":0.016954787,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.26177174,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":6,"bounds":{"left":0.04454787,"top":0.26177174,"width":0.01462766,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"bounds":{"left":0.042220745,"top":0.28411812,"width":0.024268618,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.28411812,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.044215426,"top":0.28411812,"width":0.022606382,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"bounds":{"left":0.042220745,"top":0.3064645,"width":0.04488032,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.3064645,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":20,"bounds":{"left":0.044215426,"top":0.3064645,"width":0.04720745,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":23,"bounds":{"left":0.042220745,"top":0.35913807,"width":0.034242023,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.35913807,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.045212764,"top":0.35913807,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"bounds":{"left":0.042220745,"top":0.38148445,"width":0.03756649,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.38148445,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.04488032,"top":0.38148445,"width":0.03523936,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"bounds":{"left":0.042220745,"top":0.4038308,"width":0.026263298,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.4038308,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.045212764,"top":0.4038308,"width":0.023271276,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"bounds":{"left":0.042220745,"top":0.42617717,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.42617717,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.046210106,"top":0.42617717,"width":0.027925532,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"bounds":{"left":0.042220745,"top":0.44852355,"width":0.034906916,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.44852355,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.045877658,"top":0.44852355,"width":0.03158245,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.042220745,"top":0.4708699,"width":0.03756649,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.4708699,"width":0.0033244682,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.045545213,"top":0.4708699,"width":0.034242023,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"bounds":{"left":0.07945479,"top":0.4708699,"width":0.0063164895,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"bounds":{"left":0.08211436,"top":0.4708699,"width":0.014295213,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.08211436,"top":0.4708699,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":13,"bounds":{"left":0.08610372,"top":0.4708699,"width":0.028922873,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"bounds":{"left":0.09607713,"top":0.4884278,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"bounds":{"left":0.09607713,"top":0.4884278,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11735372,"top":0.4708699,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":16,"bounds":{"left":0.1200133,"top":0.4708699,"width":0.03557181,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":23,"bounds":{"left":0.042220745,"top":0.49321628,"width":0.028922873,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.49321628,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.04488032,"top":0.49321628,"width":0.026263298,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Ves","depth":23,"bounds":{"left":0.042220745,"top":0.51556265,"width":0.0076462766,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.51556265,"width":0.0029920214,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.045212764,"top":0.51556265,"width":0.004986702,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.042220745,"top":0.53790903,"width":0.03756649,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.53790903,"width":0.0033244682,"height":0.014365523}},{"char_start":1,"char_count":15,"bounds":{"left":0.045545213,"top":0.53790903,"width":0.034242023,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":23,"bounds":{"left":0.042220745,"top":0.5602554,"width":0.031914894,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.5602554,"width":0.0019946808,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.044215426,"top":0.5602554,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"bounds":{"left":0.042220745,"top":0.5826017,"width":0.02925532,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.5826017,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":12,"bounds":{"left":0.04488032,"top":0.5826017,"width":0.026928192,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"bounds":{"left":0.07413564,"top":0.5826017,"width":0.0063164895,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.07446808,"top":0.5826017,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":2,"bounds":{"left":0.07679521,"top":0.5826017,"width":0.0056515955,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"bounds":{"left":0.042220745,"top":0.63527536,"width":0.022273935,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.63527536,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.04454787,"top":0.63527536,"width":0.019946808,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"bounds":{"left":0.042220745,"top":0.6576217,"width":0.011968086,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.6576217,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.04488032,"top":0.6576217,"width":0.009640957,"height":0.014365523}}],"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"bounds":{"left":0.042220745,"top":0.67996806,"width":0.03025266,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.042220745,"top":0.67996806,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":14,"bounds":{"left":0.045877658,"top":0.67996806,"width":0.032912236,"height":0.014365523}}],"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.10206117,"top":0.09177973,"width":0.030585106,"height":0.030327214},"on_screen":true,"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.111369684,"top":0.10055866,"width":0.01861702,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.111369684,"top":0.10055866,"width":0.0039893617,"height":0.012769354}},{"char_start":1,"char_count":7,"bounds":{"left":0.115359046,"top":0.10055866,"width":0.014960106,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"bounds":{"left":0.13397606,"top":0.09177973,"width":0.033909574,"height":0.030327214},"on_screen":true,"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.14328457,"top":0.10055866,"width":0.021941489,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.14328457,"top":0.10055866,"width":0.0033244682,"height":0.012769354}},{"char_start":1,"char_count":9,"bounds":{"left":0.1462766,"top":0.10055866,"width":0.019281914,"height":0.012769354}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":17,"bounds":{"left":0.16921543,"top":0.09177973,"width":0.020944148,"height":0.030327214},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":19,"bounds":{"left":0.17852394,"top":0.10055866,"width":0.008976064,"height":0.012769354},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.17852394,"top":0.10055866,"width":0.0026595744,"height":0.012769354}},{"char_start":1,"char_count":4,"bounds":{"left":0.18118352,"top":0.10055866,"width":0.0063164895,"height":0.012769354}}],"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.19115691,"top":0.09177973,"width":0.010970744,"height":0.030327214},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"bounds":{"left":0.096409574,"top":0.0518755,"width":0.015625,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"bounds":{"left":0.096409574,"top":0.0518755,"width":0.0076462766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"bounds":{"left":0.096409574,"top":0.0518755,"width":0.013962766,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:54:17 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:54 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"аз не съм чувал за такава но не съм и работил по planhat","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:54:45 PM","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:54","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ок мерси, ще ти пиша, или в тикет направо когато сме готови","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 21st at 1:56:12 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:56 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"oks thx","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"bounds":{"left":0.12932181,"top":0.12689546,"width":0.05817819,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 4:48:19 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4:48 PM","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Лукас","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 4:48:25 PM","depth":25,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"4:48","depth":26,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Имаш ли минутка за бърз хъдъл :?","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.11801862,"top":0.11572227,"width":0.030917553,"height":0.008778931},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.14860372,"top":0.11572227,"width":0.0029920214,"height":0.0071827616},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:49:40 PM","depth":24,"bounds":{"left":0.1512633,"top":0.11572227,"width":0.015292553,"height":0.006384677},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:49 PM","depth":25,"bounds":{"left":0.1512633,"top":0.11572227,"width":0.015292553,"height":0.006384677},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"здрасти Петко, до сега бях в среща","depth":25,"bounds":{"left":0.11801862,"top":0.12609737,"width":0.08144947,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.12609737,"width":0.0023271276,"height":0.014365523}},{"char_start":1,"char_count":33,"bounds":{"left":0.12034574,"top":0.12609737,"width":0.07912234,"height":0.014365523}}],"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:49:53 PM","depth":25,"bounds":{"left":0.107380316,"top":0.15243416,"width":0.007978723,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:49","depth":26,"bounds":{"left":0.107380316,"top":0.15243416,"width":0.007978723,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.107380316,"top":0.15243416,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.109707445,"top":0.15243416,"width":0.005984043,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"какво става","depth":25,"bounds":{"left":0.11801862,"top":0.15003991,"width":0.026595745,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.15003991,"width":0.0026595744,"height":0.014365523}},{"char_start":1,"char_count":10,"bounds":{"left":0.120678194,"top":0.15003991,"width":0.023936171,"height":0.014365523}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.12529927,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.12529927,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.12529927,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"bounds":{"left":0.11801862,"top":0.17238627,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15392287,"top":0.17398244,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:50:38 PM","depth":24,"bounds":{"left":0.15658244,"top":0.1763767,"width":0.014960106,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50 PM","depth":25,"bounds":{"left":0.15658244,"top":0.1763767,"width":0.014960106,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.1763767,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.15890957,"top":0.1763767,"width":0.012965426,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Няма проблем","depth":25,"bounds":{"left":0.11801862,"top":0.1915403,"width":0.033909574,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.1915403,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":11,"bounds":{"left":0.12200798,"top":0.1915403,"width":0.029920213,"height":0.014365523}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.15881884,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.15881884,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.15881884,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Apr 22nd at 6:50:40 PM","depth":25,"bounds":{"left":0.107380316,"top":0.21787709,"width":0.007978723,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50","depth":26,"bounds":{"left":0.107380316,"top":0.21787709,"width":0.007978723,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.107380316,"top":0.21787709,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":3,"bounds":{"left":0.109707445,"top":0.21787709,"width":0.005984043,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Оправих се","depth":25,"bounds":{"left":0.11801862,"top":0.21548285,"width":0.027260639,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.21548285,"width":0.0039893617,"height":0.014365523}},{"char_start":1,"char_count":9,"bounds":{"left":0.12200798,"top":0.21548285,"width":0.022273935,"height":0.014365523}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.19074222,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.19074222,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.19074222,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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.11801862,"top":0.23782921,"width":0.030917553,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.14860372,"top":0.23942538,"width":0.0029920214,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Apr 22nd at 6:50:56 PM","depth":24,"bounds":{"left":0.1512633,"top":0.24181964,"width":0.015292553,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50 PM","depth":25,"bounds":{"left":0.1512633,"top":0.24181964,"width":0.015292553,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15159574,"top":0.24181964,"width":0.0023271276,"height":0.011971269}},{"char_start":1,"char_count":6,"bounds":{"left":0.15392287,"top":0.24181964,"width":0.012965426,"height":0.011971269}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.22426178,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.22426178,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.22426178,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"bounds":{"left":0.14594415,"top":0.2952913,"width":0.025265958,"height":0.022346368},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"bounds":{"left":0.11801862,"top":0.3264166,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15392287,"top":0.32801276,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:11:27 PM","depth":24,"bounds":{"left":0.15658244,"top":0.33040702,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11 PM","depth":25,"bounds":{"left":0.15658244,"top":0.33040702,"width":0.017287234,"height":0.011173184},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.15658244,"top":0.33040702,"width":0.0026595744,"height":0.011971269}},{"char_start":1,"char_count":7,"bounds":{"left":0.15890957,"top":0.33040702,"width":0.015292553,"height":0.011971269}}],"role_description":"text"},{"role":"AXStaticText","text":"Лукас","depth":25,"bounds":{"left":0.11801862,"top":0.34557062,"width":0.013630319,"height":0.014365523},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.11801862,"top":0.34557062,"width":0.003656915,"height":0.014365523}},{"char_start":1,"char_count":4,"bounds":{"left":0.12167553,"top":0.34557062,"width":0.009973404,"height":0.014365523}}],"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.31284916,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.31284916,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.31284916,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:11:30 PM","depth":25,"bounds":{"left":0.105053194,"top":0.3719074,"width":0.010305851,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:11","depth":26,"bounds":{"left":0.105053194,"top":0.3719074,"width":0.010305851,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Имаш ли 2 минутки ?","depth":25,"bounds":{"left":0.11801862,"top":0.36951315,"width":0.049534574,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"bounds":{"left":0.16755319,"top":0.37110934,"width":0.0013297872,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":25,"bounds":{"left":0.16855054,"top":0.37110934,"width":0.01462766,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"bounds":{"left":0.18284574,"top":0.37110934,"width":0.0013297872,"height":0.012769354},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.34477255,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.34477255,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.34477255,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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.11801862,"top":0.39185953,"width":0.030917553,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.14860372,"top":0.3934557,"width":0.0029920214,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:47 PM","depth":24,"bounds":{"left":0.1512633,"top":0.39584997,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"bounds":{"left":0.1512633,"top":0.39584997,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"здрасти да","depth":25,"bounds":{"left":0.11801862,"top":0.41101357,"width":0.025265958,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.3782921,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.3782921,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.3782921,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"bounds":{"left":0.11801862,"top":0.43335995,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15392287,"top":0.4349561,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:55 PM","depth":24,"bounds":{"left":0.15658244,"top":0.43735036,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"bounds":{"left":0.15658244,"top":0.43735036,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Може ли да звънна?","depth":25,"bounds":{"left":0.11801862,"top":0.45251396,"width":0.046875,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.4197925,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.4197925,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.4197925,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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.11801862,"top":0.47486034,"width":0.030917553,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.14860372,"top":0.4764565,"width":0.0029920214,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:13:57 PM","depth":24,"bounds":{"left":0.1512633,"top":0.47885075,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:13 PM","depth":25,"bounds":{"left":0.1512633,"top":0.47885075,"width":0.01761968,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да","depth":25,"bounds":{"left":0.11801862,"top":0.49401435,"width":0.0056515955,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.4612929,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.4612929,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.4612929,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"A huddle happened","depth":24,"bounds":{"left":0.11801862,"top":0.5179569,"width":0.043218084,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.1612367,"top":0.5179569,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:14:01 PM","depth":24,"bounds":{"left":0.16389628,"top":0.5203512,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:14 PM","depth":25,"bounds":{"left":0.16389628,"top":0.5203512,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"You and","depth":24,"bounds":{"left":0.11801862,"top":0.5355148,"width":0.01861702,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":24,"bounds":{"left":0.13663563,"top":0.5355148,"width":0.034574468,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"were in the huddle for","depth":24,"bounds":{"left":0.11801862,"top":0.5355148,"width":0.09507979,"height":0.031923383},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"8m","depth":24,"bounds":{"left":0.12533244,"top":0.55307263,"width":0.00731383,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".","depth":24,"bounds":{"left":0.13231383,"top":0.55307263,"width":0.0013297872,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.5027933,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.5027933,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.5027933,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Petko Kashinski","depth":24,"bounds":{"left":0.11801862,"top":0.575419,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.15392287,"top":0.57701516,"width":0.0026595744,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:21:31 PM","depth":24,"bounds":{"left":0.15658244,"top":0.5794094,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:21 PM","depth":25,"bounds":{"left":0.15658244,"top":0.5794094,"width":0.017287234,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"playbackVisited","depth":25,"bounds":{"left":0.11801862,"top":0.594573,"width":0.034242023,"height":0.014365523},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"bounds":{"left":0.12865691,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.1392952,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.14993352,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.16057181,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"bounds":{"left":0.17121011,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"bounds":{"left":0.1818484,"top":0.56185156,"width":0.010638298,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"bounds":{"left":0.21476063,"top":0.56185156,"width":0.0003324468,"height":0.025538707},"on_screen":true,"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,"bounds":{"left":0.21476063,"top":0.56185156,"width":0.0003324468,"height":0.025538707},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":23,"bounds":{"left":0.10372341,"top":0.6272945,"width":0.109707445,"height":0.030327214},"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"loading…","depth":11,"bounds":{"left":0.0,"top":0.7126895,"width":0.018949468,"height":0.0007980846},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski is typing","depth":11,"bounds":{"left":0.0,"top":0.7126895,"width":0.019946808,"height":0.0007980846},"on_screen":true,"role_description":"text"}]...
|
-9066207687685814032
|
-3879404872211726252
|
visual_change
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Petko Kashinski
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Galya Dimitrova
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Ves
Aneliya Angelova
James Graham
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Apr 21st at 1:54:17 PM
1:54 PM
аз не съм чувал за такава но не съм и работил по planhat
Apr 21st at 1:54:45 PM
1:54
ок мерси, ще ти пиша, или в тикет направо когато сме готови
Petko Kashinski
Apr 21st at 1:56:12 PM
1:56 PM
oks thx
Jump to date
Petko Kashinski
Apr 22nd at 4:48:19 PM
4:48 PM
Лукас
Apr 22nd at 4:48:25 PM
4:48
Имаш ли минутка за бърз хъдъл :?
Lukas Kovalik
Apr 22nd at 6:49:40 PM
6:49 PM
здрасти Петко, до сега бях в среща
Apr 22nd at 6:49:53 PM
6:49
какво става
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Apr 22nd at 6:50:38 PM
6:50 PM
Няма проблем
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Apr 22nd at 6:50:40 PM
6:50
Оправих се
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
Apr 22nd at 6:50:56 PM
6:50 PM
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Jump to date
Petko Kashinski
Today at 12:11:27 PM
12:11 PM
Лукас
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 12:11:30 PM
12:11
Имаш ли 2 минутки ?
(edited)
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:13:47 PM
12:13 PM
здрасти да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:13:55 PM
12:13 PM
Може ли да звънна?
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:13:57 PM
12:13 PM
да
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
A huddle happened
Today at 12:14:01 PM
12:14 PM
You and
Petko Kashinski
were in the huddle for
8m
.
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Petko Kashinski
Today at 12:21:31 PM
12:21 PM
playbackVisited
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
loading…
Petko Kashinski is typing
ActivityLaterMoreslackcalVIewJiminny…..# general# jiminny-bg# platform-tickets# product_launches# random# releasesi sona-otnce# support# thank-yous# the_people_of jimi...64 Direct messages. Petko Kashinskia. Stefka StoyanovaG. Vasil VasilevC. Nikolay IvanovP. Galya Dimitrova E3 Aneliya Angelova,..2. Stoyan Tanev E@. VesA. Aneliya Angelovad. James Graham. Lukas Kovalik y...#: AppsG Jira Cloud® Toast© ExportController.php© FrontendController.ph| 1117(* FrontendControllerTra 118© GeocodingController.p 119(C) HealthCheckControllerIchController.pl 12gwases tionProviderCo 1459plavhackController nhi© PlaylistController.php146 0g >(C) PucherController nhn9a) SlackController nhnMistonWindowhelpQ Describe what you are looking for© Petko KashinskiMessagest Add canvasQ FilesWednesday. April 22nd ~ рещаKakbo clabaPetko Kashinski 6:50 PMНяма проблемОправих се ©Lukas Kovalik 6:50 PMPetko Kashinski 12:11 PMЛlукасИмаш ли 2 минутки ? (edited)Lukas Kovalik 12:13PMздрасти даPetko Kashinski 12Може ли да звъннаLukas Kovallik 12:16A hudd le hanpenedfor 8m.Petko Kashinski 12.21PMolavbackVisitedMessage Petko Kashinski+ Aal• suppont Dally • In 2n 30m100% 18• Mon 11 May 12:22:38+0 ..ontceneratedevent.onpHubSpot/Service.php@ UserAutomatedReportsController.php© SyncRelatedActivityManager.phpRematchActivityOnCrmObjectDetach.phgС) Cпескапакеtгукemotematch.phgIvityservice.oho© MatchCrmData.php( RateLimitException.php© CrmObjectsResolver.phpFrontendControllerMA6X3AYivity, PlaybackPageTransformer $transformer, Request Srequest): array|str:avlist' = Sth1s->qetPreloadedPlavu1st(Sactiv1tv)^a']['tracks'D)) {iks'Event to Planhat without slowing thefter the response is sent back.PSNPhpStormaybackbata']ravorited'E custom.log xE laravel.logA SF jiminny@localhost]A HS_Jocal (jiminny@localhost]# console [PKOb.# console [euJ# console [slAGiNg):2026-05-07 14:21:15] Local. INFO: [Hubspot] DEBUG Getting headers {w19лV"headers":{"Vace". "Inu,ur May 2020 14.21.19 6Ml"Jn"Transfer-Encoding": ["chunked"],"CF-Ray": ["9f80deb8db60dc3a-SOF"],"CF-Cache-Status": L"DYNAMIC"J,"Strict-Transport-Secur1ty":"max-aqe=31536000* 1ncludeSubDomains: preload")nacceot-encodino""access-control-allow-credentials":["false"],"server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\",cfr;desc=\"9f80deb8e7c6dc3a-IAD\""],"x-content-type-options": ["nosniff"],"x-hubspot-correlation-id": ["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],"Set-Cookie": ["__cf_bm=SIUrtdQgXVcik50pdqF6hZVYKhzTnQBidyMabeCtm0Y-1778163675-1.0.1.:07-May-26 14:51:15 GMT; domain=.hubapj.com; Http0nly; Secure; SameSite=None"],"Report-To":["fCascadeHubspot Rate Limit ReRun only 5 workers tor analytics low so concurrency naturally matches the o RPS limitO bashpho artisan queue:work --queue=analvtics low --tries= -max-iobs=0 --processes=5Effect: 5 workers x 1 successful op/sec = 5/sec. No rate-limit storms because we're under the limit by design. Each worker rarely sees a 429.Trade-oris• Slower throughput (still 5/sec ceiling = 5.5 hours for 100k)• Other jobs on this queue compete with the bottleneckWorks, but requires Horizon config changes.F. Pre-flight cache check at job entry (mentioned earlier)Eliminates the DB.transaction churn.from.cache-hit cvcles.Doesnit chande.the throughnut.ceilina.but.reduces.cost.during.a.storm.to.almost.nothinaEasy win. Pairs with all other options.G. Filter unmatchable activities betore dispatchIf many activities have no email/phone/name to match, dispatching them is pure waste:D php'eNotNull"phone")Il over 9k cap, but closer."Server": ["cloudflare"]H} {"correlation_id": "95236535-ec98-4541-b92a-adfa73b69eab","trace_10":"C/AD8565-905t-4604-9405-0e5b551e5545= Svlewprivate function getPreloadedPlaylist(Activity Sactivity): arrayt...}Othrows AuthorizationEycentionGET /playlist/(activity).m3u8 [playlist]public function playlist(Activity $activity): Responsef…..,For maximum ROI:1. A (batch endpoints) - 100x throughput. Solves the problem.2. B (dispatch throttling) - defense in depth. prevents future storms.3. C (lookup caching) - reduces redundant APl calls,4. F (pre-flight cache check) - eliminates DB churn during inevitable stormsWith A + B alone, the 100k → 9k problem becomes 100k → 100k completed in -3-10 minutes, depending on caching efficiency.A is the leverage point. Without batch endpoints, you're brute-forcing through a 5 RPS hose. With them, the hose is 500 matches/sec.SummaryRace window: 5-10 wasted real APl calls per cache iil cycle, Bounded, ~15k calls wastedlin 30 min (vs 441k without cache). Acceptables can be tiahtened with aprobe lock if needed.HubSoot-named middleware on multi-CPM iob: no functional issue for HubSnot Salesforce/Pinedrive rate-limits ao throuch the wrond nath (treated as real100k → 9k bottleneck: not a rate-limiter problem, an architectural one. The fix is batch endpoints + dispatch throttling, not more aggressive retry logic.ul .Ask anvthing (84D)÷ « CodeClaude Onus 4.7 Mediumf 4 spaces...
|
16757
|
NULL
|
NULL
|
NULL
|
|
15040
|
673
|
41
|
2026-05-11T06:10:43.467376+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-11/1778 /Users/lukas/.screenpipe/data/data/2026-05-11/1778479843467_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormVIewINavicareCodeFV faVsco.js?9 JY-20725-h PhpStormVIewINavicareCodeFV faVsco.js?9 JY-20725-handle-HS-search-rate-limitProiectC) HubsootPaginationService.ong( OutofRoundsEycention n.yhuospotsyncstrategybase.ongQuotaExceededExceptiorKateLimitexception.onp© RegistrationinvitationMisr© ermactivilyservice.phg© RequestQueuedForDeferrResponseException.php<?phpRinqCentralException.phrRingcentralExtensionNotldeclarelstrict tyoessio:RuntimeException.php( SequenceNumberExceptinamespace Jiminny Excentions:@ ServicelntegrationExcept( ServiceUnavailable Excepuse Throwable:© SidekickSettingsexceptio(4 Socia Account NotFounde(4) SocialAccountTokeninvaliclass RateLimitException extends LogicException(SvncActivitvExcention.oh( TenantisolationEyception11 0public function __construct(string Smessage = "'( TextRelavsxcention.ohv@ TooManvFailedActivitiesprivate readonly int SretryAfter = 1,4 TranscrintionNotindeyedf>Throwable Sorevious = null,@ UneynectedCallSycention4...© UnexpectedEloquentMod© UnexpectedValueExcepti1 usagepublic function getRetryAfter0: int{...}© ZipAttackException.phpD FFMpegD Formats> D Guards> M Helpers.v D Http• _ AccessI okenProviderv C Controllersv DAPI> D AiCallScorindAlReports• DeallnsiantsOoportunit• → PageScorecards• SettinasTeaminsiahts• M Themecv MUserAutomatedRer(C) UserAutomatediv DV2C) ActivitvV2Contr8) AckAnvthinaGor(C) Ack liminnvRend( NonleV2Controll(e OnNemandv2e,0 DievlictControlle"a) DiaulictCharoCnolner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (2 minutes aaoiCachedcrmservicebecorator.onp© ProspectCache.phpA SF (jiminny@localhost]4 HS_local (jiminny@localhost]# console [PKob.# console [euJ# console [slAGiNg)[2026-05-07 14:21:15] local.INF0: [Hubspot] DEBUG Getting headers {"neaders".?"Uace":L"Inu,or May 2020 14.21.15 6Ml"Jn"concenc-lyoe. apolicacion/ison.charser=utt-on"Transter-Encod1nq":"chunked")."Connection":"keep-alive""CF-Ray" : ["9f80deb8db60dc3a-SOF"],"Strict-Transport-Security":["max-aqe=31536000: includeSubDomains: preload"].accent-encodino""access-control-allow-credentials": ["false"J."server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\","x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],"So+-Cookie"." c+hm-Stlirtd0aXVr.kSandas6hzVVKhzTn0BidvMaheCtm0V-1778163675-1.0.107-May-26 14:51:15 GMT; domain=.hubapi.com; Http0nly; Secure; SameSite=None"],"Renont-To".r"*"endnoints"."unl".httns:a.nel.cloudflane.com./nenon+|W/v42c=NVA1cVTPQfVm32anS0ixVF/sd2RI"group\":\"cf-nel\","max_age\":604800}"],"NEL":["{\"success_fraction\":0.01,"report to\":|"cf-nel\"."max age":604800}"]"Server": ["cloudflare"]}} {"correlation_ 10":"95256555-ec98-4541-b9za-adta/Sboyeab"."trace_10":C/AD8565-905t-4604-9405-0e5b551e5545"CascadeNew CascadeS0 l ODally - Platrorm • In 3om100% Lz• Mon 11 May 9:10:43AskJiminnyReportActivityServiceTest+0 ..Cascade Code x• .Kick off a new project. Make changesacross your entre codeoase.^ cilo.• Ootel imitException.php app/ExcepMakefileREADME.md• INSIALL.Mlicenses.md"ohoui Plan.oho aReview @HubspotPaqinationService.pho @MatchActivitvCrmData.oho @Service.pho @RateLimitException.ohp @filel+ « CodeC° AdantiveWN Windsurf Teams22-2 UTF.8io 4 spaces...
|
NULL
|
-9065334500898444559
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormVIewINavicareCodeFV faVsco.js?9 JY-20725-h PhpStormVIewINavicareCodeFV faVsco.js?9 JY-20725-handle-HS-search-rate-limitProiectC) HubsootPaginationService.ong( OutofRoundsEycention n.yhuospotsyncstrategybase.ongQuotaExceededExceptiorKateLimitexception.onp© RegistrationinvitationMisr© ermactivilyservice.phg© RequestQueuedForDeferrResponseException.php<?phpRinqCentralException.phrRingcentralExtensionNotldeclarelstrict tyoessio:RuntimeException.php( SequenceNumberExceptinamespace Jiminny Excentions:@ ServicelntegrationExcept( ServiceUnavailable Excepuse Throwable:© SidekickSettingsexceptio(4 Socia Account NotFounde(4) SocialAccountTokeninvaliclass RateLimitException extends LogicException(SvncActivitvExcention.oh( TenantisolationEyception11 0public function __construct(string Smessage = "'( TextRelavsxcention.ohv@ TooManvFailedActivitiesprivate readonly int SretryAfter = 1,4 TranscrintionNotindeyedf>Throwable Sorevious = null,@ UneynectedCallSycention4...© UnexpectedEloquentMod© UnexpectedValueExcepti1 usagepublic function getRetryAfter0: int{...}© ZipAttackException.phpD FFMpegD Formats> D Guards> M Helpers.v D Http• _ AccessI okenProviderv C Controllersv DAPI> D AiCallScorindAlReports• DeallnsiantsOoportunit• → PageScorecards• SettinasTeaminsiahts• M Themecv MUserAutomatedRer(C) UserAutomatediv DV2C) ActivitvV2Contr8) AckAnvthinaGor(C) Ack liminnvRend( NonleV2Controll(e OnNemandv2e,0 DievlictControlle"a) DiaulictCharoCnolner Code will hoin INF to underctand vour Laravel ann code II Generate II Don't Show Anvmore (2 minutes aaoiCachedcrmservicebecorator.onp© ProspectCache.phpA SF (jiminny@localhost]4 HS_local (jiminny@localhost]# console [PKob.# console [euJ# console [slAGiNg)[2026-05-07 14:21:15] local.INF0: [Hubspot] DEBUG Getting headers {"neaders".?"Uace":L"Inu,or May 2020 14.21.15 6Ml"Jn"concenc-lyoe. apolicacion/ison.charser=utt-on"Transter-Encod1nq":"chunked")."Connection":"keep-alive""CF-Ray" : ["9f80deb8db60dc3a-SOF"],"Strict-Transport-Security":["max-aqe=31536000: includeSubDomains: preload"].accent-encodino""access-control-allow-credentials": ["false"J."server-timing": ["hcid;desc=\"019e02d0-6fd8-7812-bdba-885b7ccb3ee3\","x-hubspot-correlation-id":["019e02d0-6fd8-7812-bdba-885b7ccb3ee3"],"So+-Cookie"." c+hm-Stlirtd0aXVr.kSandas6hzVVKhzTn0BidvMaheCtm0V-1778163675-1.0.107-May-26 14:51:15 GMT; domain=.hubapi.com; Http0nly; Secure; SameSite=None"],"Renont-To".r"*"endnoints"."unl".httns:a.nel.cloudflane.com./nenon+|W/v42c=NVA1cVTPQfVm32anS0ixVF/sd2RI"group\":\"cf-nel\","max_age\":604800}"],"NEL":["{\"success_fraction\":0.01,"report to\":|"cf-nel\"."max age":604800}"]"Server": ["cloudflare"]}} {"correlation_ 10":"95256555-ec98-4541-b9za-adta/Sboyeab"."trace_10":C/AD8565-905t-4604-9405-0e5b551e5545"CascadeNew CascadeS0 l ODally - Platrorm • In 3om100% Lz• Mon 11 May 9:10:43AskJiminnyReportActivityServiceTest+0 ..Cascade Code x• .Kick off a new project. Make changesacross your entre codeoase.^ cilo.• Ootel imitException.php app/ExcepMakefileREADME.md• INSIALL.Mlicenses.md"ohoui Plan.oho aReview @HubspotPaqinationService.pho @MatchActivitvCrmData.oho @Service.pho @RateLimitException.ohp @filel+ « CodeC° AdantiveWN Windsurf Teams22-2 UTF.8io 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
8079
|
358
|
28
|
2026-05-08T09:58:49.961256+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-08/1778 /Users/lukas/.screenpipe/data/data/2026-05-08/1778234329961_m2.jpg...
|
PhpStorm
|
Unshelve Changes
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Patch file name:
/Users/lukas/jiminny/app/.idea/sh Patch file name:
/Users/lukas/jiminny/app/.idea/shelf/hubspot_rate_limit_temp_checkout/shelved.patch
Browse… (⇧⏎)
Show Difference
Change Directory Paths
Group By
Expand All
Collapse All
17 files, folder partially checked
app 16 files, folder partially checked
Console/Commands 1 file, folder not checked
JiminnyDebugCommand.php Modified, class not checked
Exceptions 1 file, folder checked
RateLimitException.php Modified, exception class checked
Jobs 8 files, folder not checked
Activity 3 files, folder not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Crm 4 files, folder not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Middleware 1 file, folder not checked
HandleHubspotRateLimit.php Added, class not checked
Services 6 files, folder not checked
Crm/Hubspot 5 files, folder not checked
Pagination 1 file, folder not checked
HubspotPaginationService.php Modified, class not checked
ServiceTraits 1 file, folder not checked
OpportunitySyncTrait.php Modified not checked
Client.php Modified, class not checked
HubspotClientInterface.php Modified, interface not checked
Service.php Modified, class not checked
PlaybackService.php Modified, class not checked
config 1 file, folder not checked
logging.php Modified not checked
app 16 files, folder partially checked
Console/Commands 1 file, folder not checked
JiminnyDebugCommand.php Modified, class not checked
Exceptions 1 file, folder checked
RateLimitException.php Modified, exception class checked
Jobs 8 files, folder not checked
Activity 3 files, folder not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Crm 4 files, folder not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Middleware 1 file, folder not checked
HandleHubspotRateLimit.php Added, class not checked
Services 6 files, folder not checked
Crm/Hubspot 5 files, folder not checked
Pagination 1 file, folder not checked
HubspotPaginationService.php Modified, class not checked
ServiceTraits 1 file, folder not checked
OpportunitySyncTrait.php Modified not checked
Client.php Modified, class not checked
HubspotClientInterface.php Modified, interface not checked
Service.php Modified, class not checked
PlaybackService.php Modified, class not checked
Console/Commands 1 file, folder not checked
JiminnyDebugCommand.php Modified, class not checked
JiminnyDebugCommand.php Modified, class not checked
Exceptions 1 file, folder checked
RateLimitException.php Modified, exception class checked
RateLimitException.php Modified, exception class checked
Jobs 8 files, folder not checked
Activity 3 files, folder not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Crm 4 files, folder not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Middleware 1 file, folder not checked
HandleHubspotRateLimit.php Added, class not checked
Activity 3 files, folder not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Crm 4 files, folder not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Middleware 1 file, folder not checked
HandleHubspotRateLimit.php Added, class not checked
HandleHubspotRateLimit.php Added, class not checked
Services 6 files, folder not checked
Crm/Hubspot 5 files, folder not checked
Pagination 1 file, folder not checked
HubspotPaginationService.php Modified, class not checked
ServiceTraits 1 file, folder not checked
OpportunitySyncTrait.php Modified not checked
Client.php Modified, class not checked
HubspotClientInterface.php Modified, interface not checked
Service.php Modified, class not checked
PlaybackService.php Modified, class not checked
Crm/Hubspot 5 files, folder not checked
Pagination 1 file, folder not checked
HubspotPaginationService.php Modified, class not checked
ServiceTraits 1 file, folder not checked...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Patch file name:","depth":1,"on_screen":false,"role_description":"text"},{"role":"AXTextField","text":"/Users/lukas/jiminny/app/.idea/shelf/hubspot_rate_limit_temp_checkout/shelved.patch","depth":1,"on_screen":false,"value":"/Users/lukas/jiminny/app/.idea/shelf/hubspot_rate_limit_temp_checkout/shelved.patch","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse… (⇧⏎)","depth":2,"bounds":{"left":0.27027926,"top":1.0,"width":0.0066489363,"height":0.0},"on_screen":false,"help_text":"Browse… (⇧⏎)","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Difference","depth":2,"bounds":{"left":0.40791222,"top":0.31843576,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Change Directory Paths","depth":2,"bounds":{"left":0.41655585,"top":0.31843576,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Group By","depth":2,"bounds":{"left":0.4275266,"top":0.31843576,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand All","depth":2,"bounds":{"left":0.796875,"top":0.31843576,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":2,"bounds":{"left":0.8055186,"top":0.31843576,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"17 files, folder partially checked","depth":4,"bounds":{"left":0.41589096,"top":0.3415802,"width":0.032247342,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app 16 files, folder partially checked","depth":5,"bounds":{"left":0.42220744,"top":0.35913807,"width":0.040226065,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Console/Commands 1 file, folder not checked","depth":6,"bounds":{"left":0.42852393,"top":0.37669593,"width":0.06881649,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyDebugCommand.php Modified, class not checked","depth":7,"bounds":{"left":0.4348404,"top":0.3942538,"width":0.09674202,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Exceptions 1 file, folder checked","depth":6,"bounds":{"left":0.42852393,"top":0.41181165,"width":0.049867023,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException.php Modified, exception class checked","depth":7,"bounds":{"left":0.4348404,"top":0.4293695,"width":0.08610372,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jobs 8 files, folder not checked","depth":6,"bounds":{"left":0.42852393,"top":0.44692737,"width":0.040226065,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Activity 3 files, folder not checked","depth":7,"bounds":{"left":0.4348404,"top":0.46448523,"width":0.045877658,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Import 2 files, folder not checked","depth":8,"bounds":{"left":0.44115692,"top":0.4820431,"width":0.043550532,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HydrateCrmDataByExternalCallIdJob.php Modified, class not checked","depth":9,"bounds":{"left":0.4474734,"top":0.49960095,"width":0.12200798,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmData.php Modified, class not checked","depth":9,"bounds":{"left":0.4474734,"top":0.5171588,"width":0.0774601,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ConferenceCrmMatcherJob.php Modified, class not checked","depth":8,"bounds":{"left":0.44115692,"top":0.53471667,"width":0.10372341,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm 4 files, folder not checked","depth":7,"bounds":{"left":0.4348404,"top":0.5522745,"width":0.038896278,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot 1 file, folder not checked","depth":8,"bounds":{"left":0.44115692,"top":0.5698324,"width":0.04488032,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportBatchJobTrait.php Modified not checked","depth":9,"bounds":{"left":0.4474734,"top":0.58739024,"width":0.0887633,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php Modified, class not checked","depth":8,"bounds":{"left":0.44115692,"top":0.6049481,"width":0.09275266,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php Modified, class not checked","depth":8,"bounds":{"left":0.44115692,"top":0.62250596,"width":0.09009308,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesJob.php Modified, class not checked","depth":8,"bounds":{"left":0.44115692,"top":0.6400638,"width":0.09208777,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Middleware 1 file, folder not checked","depth":7,"bounds":{"left":0.4348404,"top":0.6576217,"width":0.05119681,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HandleHubspotRateLimit.php Added, class not checked","depth":8,"bounds":{"left":0.44115692,"top":0.67517954,"width":0.0930851,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Services 6 files, folder not checked","depth":6,"bounds":{"left":0.42852393,"top":0.6927374,"width":0.047872342,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm/Hubspot 5 files, folder not checked","depth":7,"bounds":{"left":0.4348404,"top":0.7102953,"width":0.057845745,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Pagination 1 file, folder not checked","depth":8,"bounds":{"left":0.44115692,"top":0.7278532,"width":0.04886968,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HubspotPaginationService.php Modified, class not checked","depth":9,"bounds":{"left":0.4474734,"top":0.74541104,"width":0.10073138,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ServiceTraits 1 file, folder not checked","depth":8,"bounds":{"left":0.44115692,"top":0.7629689,"width":0.054521278,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"OpportunitySyncTrait.php Modified not checked","depth":9,"bounds":{"left":0.4474734,"top":0.78052676,"width":0.09042553,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Client.php Modified, class not checked","depth":8,"bounds":{"left":0.44115692,"top":0.7980846,"width":0.05851064,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubspotClientInterface.php Modified, interface not checked","depth":8,"bounds":{"left":0.44115692,"top":0.8156425,"width":0.094082445,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Service.php Modified, class not checked","depth":8,"bounds":{"left":0.44115692,"top":0.83320034,"width":0.061835106,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackService.php Modified, class not checked","depth":7,"bounds":{"left":0.4348404,"top":0.8507582,"width":0.08045213,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"config 1 file, folder not checked","depth":5,"bounds":{"left":0.42220744,"top":0.86831605,"width":0.040226065,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"logging.php Modified not checked","depth":6,"bounds":{"left":0.42852393,"top":0.8858739,"width":0.061835106,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app 16 files, folder partially checked","depth":4,"bounds":{"left":0.42220744,"top":0.35913807,"width":0.040226065,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Console/Commands 1 file, folder not checked","depth":5,"bounds":{"left":0.42852393,"top":0.37669593,"width":0.06881649,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyDebugCommand.php Modified, class not checked","depth":6,"bounds":{"left":0.4348404,"top":0.3942538,"width":0.09674202,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Exceptions 1 file, folder checked","depth":5,"bounds":{"left":0.42852393,"top":0.41181165,"width":0.049867023,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException.php Modified, exception class checked","depth":6,"bounds":{"left":0.4348404,"top":0.4293695,"width":0.08610372,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jobs 8 files, folder not checked","depth":5,"bounds":{"left":0.42852393,"top":0.44692737,"width":0.040226065,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Activity 3 files, folder not checked","depth":6,"bounds":{"left":0.4348404,"top":0.46448523,"width":0.045877658,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Import 2 files, folder not checked","depth":7,"bounds":{"left":0.44115692,"top":0.4820431,"width":0.043550532,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HydrateCrmDataByExternalCallIdJob.php Modified, class not checked","depth":8,"bounds":{"left":0.4474734,"top":0.49960095,"width":0.12200798,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmData.php Modified, class not checked","depth":8,"bounds":{"left":0.4474734,"top":0.5171588,"width":0.0774601,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ConferenceCrmMatcherJob.php Modified, class not checked","depth":7,"bounds":{"left":0.44115692,"top":0.53471667,"width":0.10372341,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm 4 files, folder not checked","depth":6,"bounds":{"left":0.4348404,"top":0.5522745,"width":0.038896278,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot 1 file, folder not checked","depth":7,"bounds":{"left":0.44115692,"top":0.5698324,"width":0.04488032,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportBatchJobTrait.php Modified not checked","depth":8,"bounds":{"left":0.4474734,"top":0.58739024,"width":0.0887633,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php Modified, class not checked","depth":7,"bounds":{"left":0.44115692,"top":0.6049481,"width":0.09275266,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php Modified, class not checked","depth":7,"bounds":{"left":0.44115692,"top":0.62250596,"width":0.09009308,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesJob.php Modified, class not checked","depth":7,"bounds":{"left":0.44115692,"top":0.6400638,"width":0.09208777,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Middleware 1 file, folder not checked","depth":6,"bounds":{"left":0.4348404,"top":0.6576217,"width":0.05119681,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HandleHubspotRateLimit.php Added, class not checked","depth":7,"bounds":{"left":0.44115692,"top":0.67517954,"width":0.0930851,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Services 6 files, folder not checked","depth":5,"bounds":{"left":0.42852393,"top":0.6927374,"width":0.047872342,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm/Hubspot 5 files, folder not checked","depth":6,"bounds":{"left":0.4348404,"top":0.7102953,"width":0.057845745,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Pagination 1 file, folder not checked","depth":7,"bounds":{"left":0.44115692,"top":0.7278532,"width":0.04886968,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HubspotPaginationService.php Modified, class not checked","depth":8,"bounds":{"left":0.4474734,"top":0.74541104,"width":0.10073138,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ServiceTraits 1 file, folder not checked","depth":7,"bounds":{"left":0.44115692,"top":0.7629689,"width":0.054521278,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"OpportunitySyncTrait.php Modified not checked","depth":8,"bounds":{"left":0.4474734,"top":0.78052676,"width":0.09042553,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Client.php Modified, class not checked","depth":7,"bounds":{"left":0.44115692,"top":0.7980846,"width":0.05851064,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubspotClientInterface.php Modified, interface not checked","depth":7,"bounds":{"left":0.44115692,"top":0.8156425,"width":0.094082445,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Service.php Modified, class not checked","depth":7,"bounds":{"left":0.44115692,"top":0.83320034,"width":0.061835106,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackService.php Modified, class not checked","depth":6,"bounds":{"left":0.4348404,"top":0.8507582,"width":0.08045213,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console/Commands 1 file, folder not checked","depth":4,"bounds":{"left":0.42852393,"top":0.37669593,"width":0.06881649,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyDebugCommand.php Modified, class not checked","depth":5,"bounds":{"left":0.4348404,"top":0.3942538,"width":0.09674202,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyDebugCommand.php Modified, class not checked","depth":4,"bounds":{"left":0.4348404,"top":0.3942538,"width":0.09674202,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Exceptions 1 file, folder checked","depth":4,"bounds":{"left":0.42852393,"top":0.41181165,"width":0.049867023,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException.php Modified, exception class checked","depth":5,"bounds":{"left":0.4348404,"top":0.4293695,"width":0.08610372,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitException.php Modified, exception class checked","depth":4,"bounds":{"left":0.4348404,"top":0.4293695,"width":0.08610372,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jobs 8 files, folder not checked","depth":4,"bounds":{"left":0.42852393,"top":0.44692737,"width":0.040226065,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Activity 3 files, folder not checked","depth":5,"bounds":{"left":0.4348404,"top":0.46448523,"width":0.045877658,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Import 2 files, folder not checked","depth":6,"bounds":{"left":0.44115692,"top":0.4820431,"width":0.043550532,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HydrateCrmDataByExternalCallIdJob.php Modified, class not checked","depth":7,"bounds":{"left":0.4474734,"top":0.49960095,"width":0.12200798,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmData.php Modified, class not checked","depth":7,"bounds":{"left":0.4474734,"top":0.5171588,"width":0.0774601,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ConferenceCrmMatcherJob.php Modified, class not checked","depth":6,"bounds":{"left":0.44115692,"top":0.53471667,"width":0.10372341,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm 4 files, folder not checked","depth":5,"bounds":{"left":0.4348404,"top":0.5522745,"width":0.038896278,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot 1 file, folder not checked","depth":6,"bounds":{"left":0.44115692,"top":0.5698324,"width":0.04488032,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportBatchJobTrait.php Modified not checked","depth":7,"bounds":{"left":0.4474734,"top":0.58739024,"width":0.0887633,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php Modified, class not checked","depth":6,"bounds":{"left":0.44115692,"top":0.6049481,"width":0.09275266,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php Modified, class not checked","depth":6,"bounds":{"left":0.44115692,"top":0.62250596,"width":0.09009308,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesJob.php Modified, class not checked","depth":6,"bounds":{"left":0.44115692,"top":0.6400638,"width":0.09208777,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Middleware 1 file, folder not checked","depth":5,"bounds":{"left":0.4348404,"top":0.6576217,"width":0.05119681,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HandleHubspotRateLimit.php Added, class not checked","depth":6,"bounds":{"left":0.44115692,"top":0.67517954,"width":0.0930851,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Activity 3 files, folder not checked","depth":4,"bounds":{"left":0.4348404,"top":0.46448523,"width":0.045877658,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Import 2 files, folder not checked","depth":5,"bounds":{"left":0.44115692,"top":0.4820431,"width":0.043550532,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HydrateCrmDataByExternalCallIdJob.php Modified, class not checked","depth":6,"bounds":{"left":0.4474734,"top":0.49960095,"width":0.12200798,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmData.php Modified, class not checked","depth":6,"bounds":{"left":0.4474734,"top":0.5171588,"width":0.0774601,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ConferenceCrmMatcherJob.php Modified, class not checked","depth":5,"bounds":{"left":0.44115692,"top":0.53471667,"width":0.10372341,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Import 2 files, folder not checked","depth":4,"bounds":{"left":0.44115692,"top":0.4820431,"width":0.043550532,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HydrateCrmDataByExternalCallIdJob.php Modified, class not checked","depth":5,"bounds":{"left":0.4474734,"top":0.49960095,"width":0.12200798,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmData.php Modified, class not checked","depth":5,"bounds":{"left":0.4474734,"top":0.5171588,"width":0.0774601,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HydrateCrmDataByExternalCallIdJob.php Modified, class not checked","depth":4,"bounds":{"left":0.4474734,"top":0.49960095,"width":0.12200798,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmData.php Modified, class not checked","depth":4,"bounds":{"left":0.4474734,"top":0.5171588,"width":0.0774601,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ConferenceCrmMatcherJob.php Modified, class not checked","depth":4,"bounds":{"left":0.44115692,"top":0.53471667,"width":0.10372341,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm 4 files, folder not checked","depth":4,"bounds":{"left":0.4348404,"top":0.5522745,"width":0.038896278,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot 1 file, folder not checked","depth":5,"bounds":{"left":0.44115692,"top":0.5698324,"width":0.04488032,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportBatchJobTrait.php Modified not checked","depth":6,"bounds":{"left":0.4474734,"top":0.58739024,"width":0.0887633,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php Modified, class not checked","depth":5,"bounds":{"left":0.44115692,"top":0.6049481,"width":0.09275266,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php Modified, class not checked","depth":5,"bounds":{"left":0.44115692,"top":0.62250596,"width":0.09009308,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesJob.php Modified, class not checked","depth":5,"bounds":{"left":0.44115692,"top":0.6400638,"width":0.09208777,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot 1 file, folder not checked","depth":4,"bounds":{"left":0.44115692,"top":0.5698324,"width":0.04488032,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportBatchJobTrait.php Modified not checked","depth":5,"bounds":{"left":0.4474734,"top":0.58739024,"width":0.0887633,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ImportBatchJobTrait.php Modified not checked","depth":4,"bounds":{"left":0.4474734,"top":0.58739024,"width":0.0887633,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchActivityCrmData.php Modified, class not checked","depth":4,"bounds":{"left":0.44115692,"top":0.6049481,"width":0.09275266,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php Modified, class not checked","depth":4,"bounds":{"left":0.44115692,"top":0.62250596,"width":0.09009308,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesJob.php Modified, class not checked","depth":4,"bounds":{"left":0.44115692,"top":0.6400638,"width":0.09208777,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Middleware 1 file, folder not checked","depth":4,"bounds":{"left":0.4348404,"top":0.6576217,"width":0.05119681,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HandleHubspotRateLimit.php Added, class not checked","depth":5,"bounds":{"left":0.44115692,"top":0.67517954,"width":0.0930851,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HandleHubspotRateLimit.php Added, class not checked","depth":4,"bounds":{"left":0.44115692,"top":0.67517954,"width":0.0930851,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Services 6 files, folder not checked","depth":4,"bounds":{"left":0.42852393,"top":0.6927374,"width":0.047872342,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Crm/Hubspot 5 files, folder not checked","depth":5,"bounds":{"left":0.4348404,"top":0.7102953,"width":0.057845745,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Pagination 1 file, folder not checked","depth":6,"bounds":{"left":0.44115692,"top":0.7278532,"width":0.04886968,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HubspotPaginationService.php Modified, class not checked","depth":7,"bounds":{"left":0.4474734,"top":0.74541104,"width":0.10073138,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ServiceTraits 1 file, folder not checked","depth":6,"bounds":{"left":0.44115692,"top":0.7629689,"width":0.054521278,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"OpportunitySyncTrait.php Modified not checked","depth":7,"bounds":{"left":0.4474734,"top":0.78052676,"width":0.09042553,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Client.php Modified, class not checked","depth":6,"bounds":{"left":0.44115692,"top":0.7980846,"width":0.05851064,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubspotClientInterface.php Modified, interface not checked","depth":6,"bounds":{"left":0.44115692,"top":0.8156425,"width":0.094082445,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Service.php Modified, class not checked","depth":6,"bounds":{"left":0.44115692,"top":0.83320034,"width":0.061835106,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackService.php Modified, class not checked","depth":5,"bounds":{"left":0.4348404,"top":0.8507582,"width":0.08045213,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm/Hubspot 5 files, folder not checked","depth":4,"bounds":{"left":0.4348404,"top":0.7102953,"width":0.057845745,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Pagination 1 file, folder not checked","depth":5,"bounds":{"left":0.44115692,"top":0.7278532,"width":0.04886968,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HubspotPaginationService.php Modified, class not checked","depth":6,"bounds":{"left":0.4474734,"top":0.74541104,"width":0.10073138,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ServiceTraits 1 file, folder not checked","depth":5,"bounds":{"left":0.44115692,"top":0.7629689,"width":0.054521278,"height":0.017557861},"on_screen":false,"role_description":"text"}]...
|
-9065111492359705539
|
-3912607559617694434
|
click
|
accessibility
|
NULL
|
Patch file name:
/Users/lukas/jiminny/app/.idea/sh Patch file name:
/Users/lukas/jiminny/app/.idea/shelf/hubspot_rate_limit_temp_checkout/shelved.patch
Browse… (⇧⏎)
Show Difference
Change Directory Paths
Group By
Expand All
Collapse All
17 files, folder partially checked
app 16 files, folder partially checked
Console/Commands 1 file, folder not checked
JiminnyDebugCommand.php Modified, class not checked
Exceptions 1 file, folder checked
RateLimitException.php Modified, exception class checked
Jobs 8 files, folder not checked
Activity 3 files, folder not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Crm 4 files, folder not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Middleware 1 file, folder not checked
HandleHubspotRateLimit.php Added, class not checked
Services 6 files, folder not checked
Crm/Hubspot 5 files, folder not checked
Pagination 1 file, folder not checked
HubspotPaginationService.php Modified, class not checked
ServiceTraits 1 file, folder not checked
OpportunitySyncTrait.php Modified not checked
Client.php Modified, class not checked
HubspotClientInterface.php Modified, interface not checked
Service.php Modified, class not checked
PlaybackService.php Modified, class not checked
config 1 file, folder not checked
logging.php Modified not checked
app 16 files, folder partially checked
Console/Commands 1 file, folder not checked
JiminnyDebugCommand.php Modified, class not checked
Exceptions 1 file, folder checked
RateLimitException.php Modified, exception class checked
Jobs 8 files, folder not checked
Activity 3 files, folder not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Crm 4 files, folder not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Middleware 1 file, folder not checked
HandleHubspotRateLimit.php Added, class not checked
Services 6 files, folder not checked
Crm/Hubspot 5 files, folder not checked
Pagination 1 file, folder not checked
HubspotPaginationService.php Modified, class not checked
ServiceTraits 1 file, folder not checked
OpportunitySyncTrait.php Modified not checked
Client.php Modified, class not checked
HubspotClientInterface.php Modified, interface not checked
Service.php Modified, class not checked
PlaybackService.php Modified, class not checked
Console/Commands 1 file, folder not checked
JiminnyDebugCommand.php Modified, class not checked
JiminnyDebugCommand.php Modified, class not checked
Exceptions 1 file, folder checked
RateLimitException.php Modified, exception class checked
RateLimitException.php Modified, exception class checked
Jobs 8 files, folder not checked
Activity 3 files, folder not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Crm 4 files, folder not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Middleware 1 file, folder not checked
HandleHubspotRateLimit.php Added, class not checked
Activity 3 files, folder not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Import 2 files, folder not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
HydrateCrmDataByExternalCallIdJob.php Modified, class not checked
MatchCrmData.php Modified, class not checked
ConferenceCrmMatcherJob.php Modified, class not checked
Crm 4 files, folder not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Hubspot 1 file, folder not checked
ImportBatchJobTrait.php Modified not checked
ImportBatchJobTrait.php Modified not checked
MatchActivityCrmData.php Modified, class not checked
SyncHubspotObjects.php Modified, class not checked
SyncOpportunitiesJob.php Modified, class not checked
Middleware 1 file, folder not checked
HandleHubspotRateLimit.php Added, class not checked
HandleHubspotRateLimit.php Added, class not checked
Services 6 files, folder not checked
Crm/Hubspot 5 files, folder not checked
Pagination 1 file, folder not checked
HubspotPaginationService.php Modified, class not checked
ServiceTraits 1 file, folder not checked
OpportunitySyncTrait.php Modified not checked
Client.php Modified, class not checked
HubspotClientInterface.php Modified, interface not checked
Service.php Modified, class not checked
PlaybackService.php Modified, class not checked
Crm/Hubspot 5 files, folder not checked
Pagination 1 file, folder not checked
HubspotPaginationService.php Modified, class not checked
ServiceTraits 1 file, folder not checked...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3373
|
125
|
39
|
2026-05-07T12:14:57.101097+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778156097101_m1.jpg...
|
iTerm2
|
NULL
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0la6la Support Daily - 1 m left100% <78DEV (docker)DOCKERO &1DEV (docker)882APP (-zsh)Jiminny-worker-processing-4:jiminny-worker-processing-4_00:jiminny-worker-processing-5:jiminny-worker-processing-5_00:stoppedstoppedworker-crm-update:worker-crm-update_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-download:worker-download_00: stoppedworker:worker_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-audio:worker-audio_00: stoppedworker-emails:worker-emails_00:stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugSyncing opportunity 0Syncing opportunity 25Syncing opportunity 50Syncing opportunity 75Syncing opportunity 100root@docker_lamp_1:/home/jiminny# php artisan jiminny: debugSyncing opportunity 0Syncing opportunity 25Syncing opportunity 50Syncing opportunity 75Syncing opportunity 100root@docker_lamp_1:/home/jiminny# ]-zsh• $4screenpipe"•$5-zshThu 7 May 15:14:57181₴6DEV...
|
NULL
|
-9063533438447445500
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp$0la6la Support Daily - 1 m left100% <78DEV (docker)DOCKERO &1DEV (docker)882APP (-zsh)Jiminny-worker-processing-4:jiminny-worker-processing-4_00:jiminny-worker-processing-5:jiminny-worker-processing-5_00:stoppedstoppedworker-crm-update:worker-crm-update_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-download:worker-download_00: stoppedworker:worker_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-audio:worker-audio_00: stoppedworker-emails:worker-emails_00:stoppedartisan-schedule:artisan-schedule_00: stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugSyncing opportunity 0Syncing opportunity 25Syncing opportunity 50Syncing opportunity 75Syncing opportunity 100root@docker_lamp_1:/home/jiminny# php artisan jiminny: debugSyncing opportunity 0Syncing opportunity 25Syncing opportunity 50Syncing opportunity 75Syncing opportunity 100root@docker_lamp_1:/home/jiminny# ]-zsh• $4screenpipe"•$5-zshThu 7 May 15:14:57181₴6DEV...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
24794
|
1038
|
6
|
2026-05-12T10:02:34.960761+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-12/1778 /Users/lukas/.screenpipe/data/data/2026-05-12/1778580154960_m1.jpg...
|
Slack
|
Stoyan Tanev (DM) - Jiminny Inc - 4 new items - Sl Stoyan Tanev (DM) - Jiminny Inc - 4 new items - Slack...
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Galya Dimitrova
Steliyan Georgiev
Petko Kashinski
Aneliya Angelova
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Mar 26th at 1:51:29 PM
1:51
че нали сменихме default да е през webhooks за HS
Mar 26th at 1:51:56 PM
1:51
иначе в тикет споменахте за Memory Usage Error
Mar 26th at 1:52:10 PM
1:52
аз не успах да видя такава грешка
Mar 26th at 1:52:27 PM
1:52
ако ти се случи пак, снимай ми я моля те
Stoyan Tanev
Mar 26th at 1:52:50 PM
1:52 PM
Добре, аз ползвам тази команда
php artisan crm:sync-opportunity --teamId --from
Lukas Kovalik
Mar 26th at 1:53:30 PM
1:53 PM
да и добави стратегия ако искаш на зад
1 reaction, react with raised hands emoji
1
Add reaction…
Jump to date...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Petko Kashinski","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":",","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"bounds":{"left":0.56805557,"top":0.0,"width":0.061805554,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"bounds":{"left":0.6354167,"top":0.0,"width":0.013194445,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.6354167,"top":0.0,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":2,"bounds":{"left":0.6402778,"top":0.0,"width":0.011805556,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"bounds":{"left":0.56805557,"top":0.0,"width":0.045833334,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"bounds":{"left":0.56805557,"top":0.0,"width":0.024305556,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Google Calendar","depth":23,"bounds":{"left":0.56805557,"top":0.0,"width":0.06388889,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":20,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":17,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":19,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":22,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Mar 26th at 1:51:29 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:51","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"че нали сменихме default да е през webhooks за HS","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Mar 26th at 1:51:56 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:51","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"иначе в тикет споменахте за Memory Usage Error","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Mar 26th at 1:52:10 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:52","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"аз не успах да видя такава грешка","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Mar 26th at 1:52:27 PM","depth":24,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:52","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ако ти се случи пак, снимай ми я моля те","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Stoyan Tanev","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Mar 26th at 1:52:50 PM","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:52 PM","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Добре, аз ползвам тази команда","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"php artisan crm:sync-opportunity --teamId --from","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":23,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":23,"on_screen":false,"role_description":"text"},{"role":"AXLink","text":"Mar 26th at 1:53:30 PM","depth":23,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1:53 PM","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"да и добави стратегия ако искаш на зад","depth":24,"on_screen":false,"role_description":"text"},{"role":"AXCheckBox","text":"1 reaction, react with raised hands emoji","depth":24,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":25,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Add reaction…","depth":24,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Jump to date","depth":22,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9063284651364311249
|
-644885108781016153
|
click
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Galya Dimitrova
Steliyan Georgiev
Petko Kashinski
Aneliya Angelova
Stefka Stoyanova
Vasil Vasilev
Nikolay Ivanov
Aneliya Angelova
,
Nikolay Yankov
,
Steliyan Georgiev
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Google Calendar
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Mar 26th at 1:51:29 PM
1:51
че нали сменихме default да е през webhooks за HS
Mar 26th at 1:51:56 PM
1:51
иначе в тикет споменахте за Memory Usage Error
Mar 26th at 1:52:10 PM
1:52
аз не успах да видя такава грешка
Mar 26th at 1:52:27 PM
1:52
ако ти се случи пак, снимай ми я моля те
Stoyan Tanev
Mar 26th at 1:52:50 PM
1:52 PM
Добре, аз ползвам тази команда
php artisan crm:sync-opportunity --teamId --from
Lukas Kovalik
Mar 26th at 1:53:30 PM
1:53 PM
да и добави стратегия ако искаш на зад
1 reaction, react with raised hands emoji
1
Add reaction…
Jump to date
iTerm2ShellEditViewSessionScriptsProfilesWindowHelp•DOCKER₴81DEV (-zsh)O $2APP (-zsh)883→ 0 liolec2-user@ip-10-30-129-190:~ec2-user@ip-10-30-129-..X4• Support Daily - in 1h 58 m100% C78• Tue 12 May 13:02:34181-zshX5screenpipe"O 886-zsh+Fordocumentation,visit [URL_WITH_CREDENTIALS] ~]$ dockerexec-it $(dockerps --format "{{.ID}}" --filter "name=ecs-worker" | head -1) /bin/bash -c "cd /home/jiminny && bash"root@a3efaa2235c4:/home/jiminny# php artisantinkerPsy Shellv0.12.21 (PHP8.3.30cli) by Justin HilemanNew PHPmanualis available (latest:3.0.5).Update with"doc --update-manual'> Sresult = AutomatedReportResult::find(1872);[!] Aliasing'AutomatedReportResult' to'Jiminny\Models\AutomatedReportResult' for this Tinker session.Jiminny\Models\AutomatedReportResult{#15863id:1872,uuid: b"CO-0,/a\e¢Ht°ão11",report_id:54,name: "Coaching Profiles - 6 - 12 Apr 2026 - Client Success, UK Sales",media_type: "pdf",parent_id: null,status: 2,reason: 0,payload: "["team_id":1, "request_id": "822fa41b-afd3-43a9-a248-86b0e36f3131", "report_type": "coaching_profiles", "media_types": ["pdf","podcast"], "from_date": "2026-04-06T00:00:00+(0- 00- er ), te2uro-0012723:5905050:80, Canldurdt n.m,2), Conseal-5t Se (), requene dets sta ** (, akur -netue 1, meah, TOUyuaae*:apl, imn -ons E° conterrepertsVrepon, reore-pertd:°82272 10- 202-1, 09-0160-k cot6riss, 5,'eus* compt"ted", '"'inestamp" "2026-04-13701:11:48. 648399-00-:00', 's3_url" "S3:V//jiminny.client-dataV/5F0F4810-7e77-4086-8f69-93429ae4d70b\/reports\/822fa41b-afd3-43a9-a248-86b0e36f3131.MD","report_type":"coaching_profiles", "podcast_url":"s3:\Wjiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/reports\/822fa41b-afd3-43a9-a248-86b0e36f3131_podcast.txt","podcast_audio_url":"s3:\//jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70bV/reports\/822fa41b-afd3-43a9-a248-86b0e36f3131_podcast.mp3","podcast_ssml_url":"s3:\//jiminny.client-data\/Sf0f4810-7e77-4086-8f69-93429ae4d70bVreports\/822fa41b-afd3-43a9-a248-86b0e36f3131-podcast.senl"t": +2026-04-13 01:00:57"requested_at:generated_at: "2026-04-13 01:11:48",sent_at: null,created_at: "2026-04-13 01:00:27",updated_at: "2026-04-13 01:11:48",› Sresult->status = 4;› Sresult->saveO);true> exitINFOGoodbye.root@a3efaa2235c4:/home/jiminny#l...
|
NULL
|
NULL
|
NULL
|
NULL
|